Search code examples
angulartypescriptrxjsobservableswitchmap

Force call inner observable of switchMap if outer observable returned an error


My code:

    return this.userService.getPosition().pipe(
      switchMap(() => {
        return this.get('/places', { point: this.userService.coords });
      }),
    );

There can be a case, when the position cannot be retrieved (no https in Google Chrome, or user did not allowed).

In this case I still need to return return this.get('/places', { point: this.userService.coords });

Just in this call, this.userService.coord will be null.

Service code:

export class UserService {
  constructor() {}

  coords: Coordinates;

  getPosition(): Observable<any> {
    return new Observable(observer => {
      if (window.navigator && window.navigator.geolocation) {
        window.navigator.geolocation.getCurrentPosition(
          position => {
            this.coords = [position.coords.latitude, position.coords.longitude];
            observer.next(this.coords);
            observer.complete();
          },
          error => observer.error(error),
        );
      } else {
        this.coords = null;
        observer.error('Unsupported Browser');
      }
    });
  }
}

Currently - if the outer observable returned an error, the inner observable is not called(returned).


Solution

  • You can use catchError for this.

    I don't really know the actual types you use, but it should look something like this.

    Example:

    return this.userService.getPosition().pipe(
      catchError((error) => {
          // We catched the error and are telling the pipeline to continue and
          // use the provided value.
          return of(this.userService.coords);
      }),
      switchMap(point => {
        // The following line will be reached regardless of any error that has occurred earlier in the pipeline.
        return this.get('/places', { point: point });
      }),
    );