Dany D
Dany D

Reputation: 1189

How to resume RxJs Observable Interval on Error

I am merging two Observables. The first one gets the current temperature on init. The second one polls at a certain interval the API. If the Api call fails, then the Observable interval is not resumed.

How could I resume it?

getCurrentTemp(): Observable<number> {
    return this.http.get(this.environmentService.getTemperatureUrl())
      .map((res: Response) => res.json())
      .switchMap(() => res.temp);
  }

  pollCurrentTemperature(): Subscription {
    const temp$ = this.getCurrentTemp();
    const tempInterval$ = Observable
      .interval(3000)
      .flatMap(() => this.getCurrentTemp());

    return temp$
      .take(1)
      .merge(tempInterval$)
      .subscribe((temp: number) => {
        console.log('temp', temp);
      }, (err) => {
        console.log('error', err);
        // When the api fails my interval does not resume. How can I retry it?
      });
  }

Any ideas? Ty

Upvotes: 2

Views: 2187

Answers (2)

flak37
flak37

Reputation: 895

Use catch.

Catch: recover from an onError notification by continuing the sequence without error

getCurrentTemp(): Observable<number> {
    return this.http.get(this.environmentService.getTemperatureUrl())
      .map((res: Response) => res.json())
      .catch(error => {
          console.log('Error occured');
          return Observable.empty();
       });
      .switchMap(() => res.temp);
}

It will catch the error and silently return an empty observable in its place. In effect, the switchmap will skip over the failed api call silently as it will not emit for the empty observable.

Of course, you could have an alternate behaviour on error, but you need to catch it to avoid the problem you are facing.

Upvotes: 1

Radu Cojocari
Radu Cojocari

Reputation: 1779

Using the http status codes you can retrieve an observable only if its a 200 let's say:

 getCurrentTemp(): Observable<number> {
    return Observable.from(
      [
        { value: 1, status: 200 },
        { value: 2, status: 200 },
        { value: 3, status: 200 },
        { value: 4, status: 200 },
        { value: 5, status: 200 },
        { value: 6, status: 400 }])
      .switchMap((x: any) => {
        if (x.status === 200) {
          return Observable.of(x.value);
        }
        return Observable.onErrorResumeNext();
      });
  }

  pollCurrentTemperature(): Subscription {
    const temp$ = this.getCurrentTemp();
    const tempInterval$ = Observable
      .interval(3000)
      .flatMap(() => this.getCurrentTemp());

    return temp$
      .take(1)
      .merge(tempInterval$)
      .subscribe((temp: number) => {
        console.log('temp', temp);
      }, (err) => {
        console.log('error', err);
        // When the api fails my interval does not resume. How can I retry it?
      });
  }

The important bit is this return Observable.onErrorResumeNext();

Upvotes: 0

Related Questions