Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timer stops whenever an error occurred in the subscription

I have a service which run a timer in its constructor. The timer calls an asynchrony function which call an API and should return an Observable. It is running fine when everything is OK. I'm trying to implement error handling now, whenevr the API is down. The problem is that whenever an error occurred, the timer executions stops.

See my code:

subscription : Subscription;
constructor(private httpClient : HttpClient)
{
    this.subscription = timer(0, 10000).pipe
    (
        switchMap(() => this.getData();
    }).subscribe();
}


getData(): Observable<someModel>
{
    return this.httpClient.get<someModel>(<url>)
    .pipe(
    tap(response => 
    {
        do something 
    }),
    catchError(error =>
    {
        <doSomeErrorHandling>
        return throwError(error);
    })
    );
}
like image 653
Guy E Avatar asked Oct 31 '25 22:10

Guy E


2 Answers

The observable is closed when an error occurs. So instead of forwarding the error using throwError function, you could convert it to a next notification using of function. If you're worried it might tangle up the actual response handling mechanism, you could using RxJS NEVER constant to not emit anything from the catchError block.

Try the following

import { of, NEVER } from 'rxjs';
getData(): Observable<someModel>{
  return this.httpClient.get<someModel>(<url>).pipe(
    tap(response => {
      do something
    }),
    catchError(error => {
      // <doSomeErrorHandling >
      return of(error); // (or) return NEVER;
    })
  );
}

Also try to use tap only for side-effects. In your case with only a single switchMap you could handle the notifications inside the subscription.

like image 192
ruth Avatar answered Nov 03 '25 12:11

ruth


switchMap emits an error if any of it's inner observables [this.getData(), in this case], error. In instead, you likely want to catch errors on the inner observables themselves.

Remember also that a RxJS steams emit one error or one complete emission. Never more and never both. If an error reaches your switchMap, that part of your stream is done for good. You can, instead, use retry to re-create the the stream from scratch.

subscription : Subscription;
constructor(private httpClient : HttpClient){
  this.subscription = timer(0, 10000).pipe(
    switchMap(_ => this.getData().pipe(
      catchError(err => /*Do something*/)
    )
  ).subscribe();
}
like image 44
Mrk Sef Avatar answered Nov 03 '25 12:11

Mrk Sef



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!