Reputation: 45
I am using Angular 5 and have the following problem:
I have a route which contains a parameter year. The related component should now display the data for that year which is retrieved by a service. When first routing to such an URL, this works fine. If I change the parameter year, the component is not reloaded (as expected), just OnInit() is called again. In this method, I try to reload the data by calling the service method with the new year, but it does not work. Here is my code:
test.component.ts:
public ngOnInit() {
this.route.paramMap.subscribe( params => {
if (params.has('year')) {
this.loadData(params.get('year'));
} else {
this.loadData();
}
});
}
public loadData(year?: string): void {
this.testService.getData(year).subscribe(data => {
// edit and set to variables
});
}
test.service.ts:
public getData(year) {
return Observable.forkJoin(
this.getPart1(year),
this.getPart2(year)
);
}
private getPart1(year): Observable<CustomObject[]> {
let url = this.baseUrl;
if (year) url = url.concat("?year=" + year);
return this.http.get<CustomObject[]>(url, httpOptions).pipe(
catchError(this.handleError<CustomObject[]>())
)
}
private getPart2(year): Observable<OtherCustomObject[]> {
let url = this.baseUrl + '/path';
if (year) url = url.concat("?year=" + year);
return this.http.get<OtherCustomObject[]>(url, httpOptions).pipe(
catchError(this.handleError<OtherCustomObject[]>())
)
}
How to force the Observable to reload the HTTP request? I tried using a (Replay)Subject instead of Observables, but that didn't work.
Any help is highly appreciated :)
Upvotes: 3
Views: 3781
Reputation: 8731
You can use a BehaviorSubject
for that with switchMap
:
//First of all, create your reloader subject
reloader$ = new BehaviorSubject(null);
//Then connect it to your observable
public getData(year) {
return this.reloader$.switchMap(() => Observable.forkJoin(
this.getPart1(year),
this.getPart2(year)
));
}
Because this is a BehaviorSubject
, the first call will work like a charm as it will give null
as first value.
Then, you can create a basic reload() method:
public reload(){
this.reloader$.next(null);
}
Because this will make reloader$
observable emit a new value, the rest of the observable chain will be triggered again, making new requests to reload your data.
Upvotes: 3