Why does my observable doesn't catch error and stops working

47 views Asked by At

I have a form. The user enters inputs and then a http request is sent to the backend to get data.

In the HTML template I have

data$ | async

In the component code I first have:

  data$: Observable<DataResponse> = this.userInput$.asObservable()
      .pipe(
          tap(() => this.loadingService.show()),
          switchMap(userInput => this.dataService.getData(
              userInput.textInput,
              userInput.numberInput).pipe(
                  finalize(() => this.loadingService.hide())
              )
          )
      );

It worked fine when there is no error. But when this.dataService.getData(...) returns an error (HttpErrorResponse); the observable stops sending request now.

I've tried to add catchError in many places but doesn't seem to work. It seems the catchError doesn't catch anything even when there is an error. Any advice would be appreciate tanks.

  data$: Observable<DataResponse> = this.userInput$.asObservable()
      .pipe(
          tap(() => this.loadingService.show()),
          switchMap(userInput => this.dataService.getData(
              userInput.textInput,
              userInput.numberInput).pipe(
              catchError(error => {
                console.error('Error occurred:', error);
                return of(null);
              }),
                  finalize(() => this.loadingService.hide())
              )
          )
      );
2

There are 2 answers

0
Zerotwelve On

your code is fine and the idea to catch the error directly in switchMap is correct, but this only works if this.dataService.getData() throws an error with throwError for example: return throwError(() => new Error("oh nooo")); but it's won't work if it throws an error like this: throw new Error('oh noooo');.

so what you have to do is to wrap your this.dataService.getData() in a try/catch block. This should solve your problem

0
jburtondev On

Throw an error manually in your service because catchError will trigger when seeing an error in the observable stream.

For example:

 of('day', 'midday', 'night')
    .pipe(
      map(timeOfDay => {
        if (timeOfDay === 'midday') {
          throw 'too early!';
        }
        return timeOfDay;
      }),
      catchError(err => {
        console.log(err) // 'too early!'
      })
    )