Can someone explain the concepts of Subject and BehaviorSubject in Angular to me? I'm new to Angular and struggling to understand.
I've tried searching online, but I still can't grasp how they work. The same goes for Observable and Observer - I'm having trouble understanding the underlying principle.
From what I've gathered, services are used to store global logic that is shared across multiple components (such as API interactions), while components.ts only store logic specific to that component.
For example, I'm working on a weather app with the following setup:
- In 'weather.service.ts', I handle API requests and process the data to return an Array of Weather objects (defined by a dedicated class).
- In 'Weather.model.ts', I define the structure of the Weather class.
- 'search.component.ts' serves as the main component.
I passed the data from 'weather.service.ts' to 'search.component.ts' using an Observable, though I'm not sure if that was the correct approach.
Code snippet from 'weather.service.ts'
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Weather } from '../models/Weather.model';
@Injectable({
providedIn: 'root'
})
export class WeatherService {
APIKEY: string = "&appid=...";
URI: string = "https://api.openweathermap.org/data/2.5/forecast?q=";
constructor(private httpClient: HttpClient) { }
getWeather(city): Observable<Weather[]> {
//Fetch city data from the API:
return this.httpClient.get(this.URI + city + this.APIKEY).pipe(map(
(data: any) => {
var weatherArray: Array<Weather> = [];
for (var i = 0; i < data.list.length; i++) {
weatherArray.push(new Weather(
data.list[i].dt,
data.list[i].main.temp,
data.list[i].main.temp_min,
data.list[i].main.temp_max,
data.list[i].main.feels_like,
data.list[i].main.pressure,
data.list[i].main.humidity,
data.list[i].weather[0].main,
data.list[i].weather[0].icon,
data.list[i].clouds.all,
data.list[i].wind.speed,
data.list[i].wind.deg
));
}
return weatherArray;
}
));
}
}
Code snippet from 'Weather.model.ts'
export class Weather {
date: Date;
temp: number;
tempMin: number;
tempMax: number;
tempFelt: number;
pressure: number;
humidity: number;
weatherDesc: string;
weatherIcon: string;
clouds: number;
windSpeed: number;
windOrientation: number;
constructor(date: Date,
temp: number,
tempMin: number,
tempMax: number,
tempFelt: number,
pressure: number,
humidity: number,
weatherDesc: string,
weatherIcon: string,
clouds: number,
windSpeed: number,
windOrientation: number) {
}
}
Code snippet from 'search.component.ts'
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { WeatherService } from 'src/app/services/weather.service';
import { Observable } from 'rxjs';
import { Weather } from '../../models/Weather.model';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
searchedCity: string;
weatherItems: Array<Weather>;
constructor(private router: Router,
private route: ActivatedRoute,
private weatherService: WeatherService) { }
ngOnInit(): void {
//Get the city name if available:
if (this.route.snapshot.params['city']) {
this.searchedCity = this.route.snapshot.params['city'];
this.weatherService.getWeather(this.searchedCity).subscribe(
(data) => {
this.weatherItems = data;
}, (err) => {
console.log(err);
});
}
}
}