I am currently building an Angular application where I make a request to an api, and I map the repsonse to two different arrays. I can use this data in my app.components.t
This is an answer describing how it can be done using pure RxJS. Another alternative is to use NgRx.
Firstly, you have set up two subjects. The intention being that all components will subscribe to them and receive the latest data when it is refreshed?
You should use ReplaySubject
instead of BehaviorSubject
though, since you don't have any initial state. And since the data comes back as one thing, I would use one subject.
Firstly, I am going to declare an interface to make it easier to talk about the data types.
earthquake-data.ts
export interface EarthquakeData {
// TODO: create types for these
geometries: any[];
properties: any[];
}
In your service, you can separate the retrieval and the notifications by exposing the data via your own methods.
earthquake.service.ts
url = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson';
private _earthquakeData$ = new ReplaySubject(1);
constructor(private readonly httpClient: HttpClient) {}
getEarthquakeData(): Observable {
// return the subject here
// subscribers will will notified when the data is refreshed
return this._earthquakeData$.asObservable();
}
refreshEarthquakeData(): Observable {
return this.httpClient.get(this.url).pipe(
tap(response => {
// notify all subscribers of new data
this._earthquakeData$.next({
geometries: response.features.map(x => x.geometry),
properties: response.features.map(x => x.properties)
});
})
);
}
So now, all components that want to receive data will subscribe to one method:
private destroyed$ = new Subject();
ngOnInit()
this.earthquakeService.getEarthquakeData().pipe(
// it is now important to unsubscribe from the subject
takeUntil(this.destroyed$)
).subscribe(data => {
console.log(data); // the latest data
});
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
And you can refresh the data wherever you want to:
refreshData() {
this.refreshing = true;
this.earthquakeService.refreshEarthquakeData().subscribe(() => {
this.refreshing = false;
});
}
DEMO: https://stackblitz.com/edit/angular-uv7j33