I have two merged observables with a scan after the merge. The first one is a simple range and the other is a Subject. Whenever the Subject emits a new value with onNext
I concatenate that value in the scan and return the new array as the accumulator. If I dispose of my subscription, and then subscribe again it replays the values from the range but I have lost the ones from the Subject. In the code below I want my second subscription to have a final value of [1, 2, 3, 4, 5]
What would be the best way to do this? Right now I have another Subject where I store that final value and subscribe to that, but it feels wrong.
Here's a simple version that demonstrates what is happening:
var Rx = require('rx');
var source = Rx.Observable.range(1, 3);
var adder = new Rx.Subject();
var merged = source.merge(adder)
.scan([], function(accum, x) {
return accum.concat(x);
});
var subscription1 = merged.subscribe(function(x) {console.log(x)});
adder.onNext(4);
adder.onNext(5);
subscription1.dispose();
console.log('After Disposal');
var subscription2 = merged.subscribe(function(x) {console.log(x)});
This outputs:
[ 1 ]
[ 1, 2 ]
[ 1, 2, 3 ]
[ 1, 2, 3, 4 ]
[ 1, 2, 3, 4, 5 ]
After Disposal
[ 1 ]
[ 1, 2 ]
[ 1, 2, 3 ]
A Subject is a hot Observable, that's why the second subscription won't see events coming from the Subject. The range Observable is cold, so each "execution instance" is entirely owned by each subscription. On the other hand, a Subject's "execution instance" is singleton and independent, hence the second subscription doesn't see the events.
There are a couple of ways of solving this.
However, if my interpretation of this problem is correct, you only need the last event emitted by merged
, so you could use a variant of alternative (1) where you replay only the last event. That would be a matter of adding .shareReplay(1)
to merged
, which will make it a hot replayed Observable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With