user7898461
user7898461

Reputation:

Signal when a ReplaySubject has "finished"

I am trying to figure out a good way to signal that a ReplaySubject is currently "empty".

import {ReplaySubject} from 'rxjs/ReplaySubject';
const rs = new ReplaySubject<Object>();

 // ...
constructor(){
  this.sub =  rs.subscribe(...);
}

everytime the constructor is called, it will replay all the items from the subject. However my question is - is there some event we can listen for, that tells us when the subject becomes empty?

The only thing that I can think of is to fire a custom/different event when subject is done, something like this:

rs.next({done:true});

is passing data to the next() method the best way to signal that ReplaySubject is (temporarily) empty/out of events?

Upvotes: 1

Views: 4475

Answers (2)

Voskanyan David
Voskanyan David

Reputation: 1177

Because Subject is also an Observer you can call complete() after the final next() call. Then you can listen it with 3rd parameter of subscribe(...) method.

const rs = new ReplaySubject<Object>();
rs.next({a: 1})
rs.complete()

rs.subscribe(
    obj => console.log(obj),
    error => {},
    () => console.log('completed')
);
// Outputs
// {a: 1} completed

Upvotes: 5

Miller
Miller

Reputation: 2822

Well now, I suppose you could setup a secondary observable to tell you what the last item being replayed is:

const last$ = rs.replay(1);

Then you'd just combineLatest and scan ... once you've reached the item emitted by last$ then your ReplaySubject has finishing replaying:

this.sub = Observable.combineLatest(
  rs,
  last$.take(1)
).scan((acc: { item: Object, isReplay: boolean }, curr: [Object, Object]) => {
    return {item: curr[0], isReplay: acc.isReplay && curr[0] !== curr[1]};
  }, {isReplay: true}
).subscribe(...);

Upvotes: 1

Related Questions