Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep observable chain going after http error in one observable

I've got a chain of observables. Here is the piece of code:

        //get dynamic tree 
      flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
      tap(res => this.dynamicTree = res),
        //get dynamic report 
      flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),

However when I got 500 API error from the first request(get dynamic tree), the chain stops and never enters the second flatMap(dynamic report).

Here is the function this.reportService.getDynamicTree():

 get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
    return this.http.get(`${environment.apiBaseUrl}${path}`, {headers: this.setHeaders(true), params: params}).pipe(
      catchError(error => this.processError(path, error)),
      map((res: Response) => res));
  }

where this.processError returns observableThrowError(res);

What should I return in case of error to continue the chain? Or is the reason in other things?

like image 647
Konstantin Kim Avatar asked Feb 06 '20 06:02

Konstantin Kim


1 Answers

In case of an error, an Observable completes, so if you want to return a new Observable after an error occurs, you have to use the catchError operator like this:

//get dynamic tree 
flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
tap(res => this.dynamicTree = res),
catchError(() => of({})),
//get dynamic report 
flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),

The tap operator safely doesn't execute the callback and just forwards errors when they occur so that will assign this.dynamicTree only in case of a success.

If you want to handle the error in the service instead of the component, you have to return something else than observableThrowError(res); from processError (for example of({})) but that will execute the tap callback and assign this.dynamicTree which is probably an unwanted behavior.

like image 108
Guerric P Avatar answered Sep 23 '22 13:09

Guerric P