Flo
Flo

Reputation: 45

Angular - Reload HTTP request

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

Answers (1)

Supamiu
Supamiu

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

Related Questions