简体   繁体   中英

rxjs: how to return the result from another observable from catchError

I'm using rxjs 6.5 and angular. Basically, I want to have a method in my service that:

  • returns the status from a 1st api calls if the api responds
  • returns the status from a 2nd (different) api call if the 1st one failed
  • returns a dummy value if that 2nd call failed

Here is what I have so far. I think I need to use flatMap/mergeMap , but I cannot figure how.

service.ts

public getStatus()
  {
    return this.http.get('http://api.com/status1')
      .pipe(
        catchError(() => {
            //makes 2nd api call here
            return this.http.get('http://api.com/status2')

            .pipe(catchError(() =>
            {
              //both calls failed
              return of({
                  data: 'blah',
                  success: false
                });

            }))

        }));
  }

component.ts

this.service.getStatus().subscribe(status=>this.status = status);

Could somebody help?

Your method works, but doesn't look that nice with nested pipes. There is one easy thing you could do though:

      // Use 'of' operator to "fake" a successful API call.
      // Use 'throwError' operator to "fake" a failed API call.
      public getStatus()
      {
        return of('firstApiCall')
          .pipe(
            catchError(() => {
              //makes 2nd api call here
              return of('secondApiCall')
            }),
            catchError(() =>
              {
                //both calls failed
                return of({
                    data: 'blah',
                    success: false
                  });
              })
          );
      }

You can extract the second catchError block to have all operators on one level - catchError operator will only trigger once the observable throws an error, and since you want a different error handling for each call, this would do.

Potentially you could also handle that with only one catchError block and do some checks of the request URL to determine what do you want to return, but I guess that would require more logic and is not worth it.

Please take a look into the provided stackblitz to see this in action:

https://stackblitz.com/edit/angular-rfevnt

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM