bygrace
bygrace

Reputation: 5988

Call API on interval when subscribed

So I wanted to setup an stream that will only get data when it is subscribed to. If there are multiple subscriptions then I want it to multi-cast to avoid excessive api calls and to cache the last known good so that future subscribers will get the data without having to hit the api. While someone is subscribed I'd like for the data to be refreshed on an interval.

I tried to do all of this with the shareReplay(n) operator. It does everything I want except that it doesn't unsubscribe from the timer when everyone unsubscribes from it (refCount === 0). See example below:

const subscription = Rx.Observable.timer(0, 1000)
  .do((x) => { console.log('timer 1', x); })
  .switchMap(() => {
    console.log('call the api');
    return Rx.Observable.of('my api call');
  })
  .shareReplay(1)
  .do((x) => { console.log('timer 2'); })
  .subscribe(
      (x) => { console.log('data', x); }
  );

setTimeout(() => {
    console.log('unsubscribe');
    subscription.unsubscribe();
}, 2500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.7/Rx.min.js"></script>

The reason seems to be that it additionally waits for the inner observable to complete:

https://github.com/ReactiveX/rxjs/blob/b25db9f369b07f26cf2fc11714ec1990b78a4536/src/internal/operators/shareReplay.ts#L45

Is there a better operator (or sequence of operators) to use to accomplish this? I'd rather avoid recreating the shareReplay operator just to remove that condition.

Upvotes: 0

Views: 332

Answers (1)

bygrace
bygrace

Reputation: 5988

Figured out right after posting this that publishReplay(1).refCount() does what I described. I am leaving this question around for anyone else that runs into that gotcha.

So publishReplay(1).refCount() is not the same thing as shareReplay(). It looks like it was from 5.4.0 till 5.5.0-beta4. Apparently that was a bug and here is the related pr: https://github.com/ReactiveX/rxjs/pull/2910

And I'm not the only confused soul: https://github.com/ReactiveX/rxjs/issues/3034

Upvotes: 1

Related Questions