nehalist
nehalist

Reputation: 1496

Observable polling in RxJs 6

Just wanted to migrate some of my legacy code to a newer version of RxJs. The code was used for polling:

Observable
  .interval(5000)
  .startWith(0)
  .switchMap(() => this.apiService.getData())
  .subscribe(data => /* ... */)

This worked fine in RxJs 5.2.0.

In RxJs 6.0.0 this doesn't work for multiple reasons (Observable only method is create, interval seems to be static, no method chaining, ...).

How to do this in latest RxJs?

Upvotes: 0

Views: 3809

Answers (2)

Anis Tissaoui
Anis Tissaoui

Reputation: 884

Referencing LeeCampbell's RxCookbook about reactive programming. Using interval is actually not practical. Because if you don't get a response from this.apiService.getData() in the interval value another value will be emitted by the interval and a new request is performed.

What you need to do is use a timer that emits a single value, use a switchMap to perform your request, and a repeat to poll again after success. Also, you can use a retry before the repeat if you want to retry after errors.

This is the implementation in C# using Rx.Net (Ref) :

public static IObservable<T> Poll<T>(this IObservable<T> request, TimeSpan period, IScheduler scheduler)
{
    return Observable.Timer(period, scheduler)
      .SelectMany(_ => request)
      .Retry()    //Loop on errors
      .Repeat();  //Loop on success
}

Which can be translated to RxJS 6 as following:

timer(5000).pipe(
    switchMap(tick => this.apiService.getData()),
    retry(3), // retry 3 times before bubbling an error
    repeat()
);

Further enhancements can be found in the LeeCampbell's RxCookbook .

Upvotes: 1

jacekbj
jacekbj

Reputation: 631

I did not run it:

interval(5000).pipe(
    switchMap(() => this.apiService.getData())
).subscribe(data => /* ... */)

Interval is now a function that returns an Observable and transformations are chained inside pipe function.

Upvotes: 4

Related Questions