chris01
chris01

Reputation: 12321

Angular/RxJS: keep interval running even in case of an error

I need to call a REST-service every 10 seconds. The REST-client call is inside an angular-service (myservice, function foo).

 ngOnInit ()
 {
      interval (10000).pipe (startWith (0), mergeMap (obs =>
      this.myservice.foo ())).subscribe (resp =>
      {
        this.data = resp;
      },
      error =>
      {
        console.log ("error");
      }
      );
 }

That is working as long the connection to the REST-service is ok. But if I stop it, then the interval stops too.

What do I need to do to keep it running (and failing) even if the REST-service is off?

Upvotes: 3

Views: 2123

Answers (4)

Teddy Sterne
Teddy Sterne

Reputation: 14221

FlatMap the value to an inner observable which handles the error. On the inner observable add a catchError handler to the pipe that handles the error silently with an empty observable. Example:

interval(10000).pipe(
  flatMap(num => of(num).pipe(
    mergeMap(num => this.myservice.foo()),
    catchError((error) => {
      console.log ("error");
      return empty();
    })
  ))
).subscribe(resp => {
  console.log(resp)
});

Stackblitz

Upvotes: 1

Radosław Roszkowiak
Radosław Roszkowiak

Reputation: 6871

How about cathing the error on the "inner" observable (the one that may actually produce errors), not the whole stream? Something like:

ngOnInit () {
  interval(10000).pipe(
    startWith(0),
    mergeMap(obs => this.myservice.foo().pipe(
      catchError((error) => {
        console.log(error);
        return empty(); // or return of(error) and do sth about it in the subscribe body
      }),
    ),
  )).subscribe(resp => this.data = resp);
}

Upvotes: 4

DeborahK
DeborahK

Reputation: 60518

This is not a specific answer to the specific scenario (I would want to have a stackblitz to try it out before attempting to post suggested code). But here is a screen shot from a video that discusses error isolation from the great Ward Bell.

enter image description here

Notice the "wrong way" and "right way" comments above the two segments of code.

You can find this part of the talk here: https://www.youtube.com/watch?v=q--U25yPTrA&feature=youtu.be&t=1240

Upvotes: 3

Suresh Kumar Ariya
Suresh Kumar Ariya

Reputation: 9764

You can use retyWhen error operator

interval (10000)
  .pipe(
    startWith(0),
    switchMap (obs => this.myservice.foo()),
    retryWhen(error => {
      return error.flatMap((error: any) => {
          if(error.status  === 503) {
              return Observable.of(true);
          }
          return Observable.throw({error: 'No retry'});
      });
);

Upvotes: 1

Related Questions