[Fixed] Optionally emit a value on a replay subject depending on its buffer value

Issue

How can I optionally emit a value on a ReplaySubject depending on its previous value. In this case, a function call might emit a value, but I don’t want it to emit if that value is an initial/default value and another value has already been emitted. For example (in an Angular service):

emitter$ = new ReplaySubject(1)

updateValue () {
  const newValue = getNewValue()
  if (newValue) {
    emitter$.next(newValue)
  } else {
    // Only emit the default value if another value has not been emitted.
    // if (emitter has already emitted something) do nothing
    // if (emitter has not already emitted something) emit a default value
  }
}

Here I don’t want to reset the value of the emitter$ to the default value if it has been changed. Subscribing to emitter$ in the else block with a take(1) to get the last value won’t work because the emitter might not have emitted anything yet.

Solution

you could combine and then map it back to the original after applying a filter

emitter$ = new ReplaySubject(1);
trigger = new BehaviourSubject(false);

watchMe$ = combineLatest(emitter$, trigger).pipe(
    map(([emitter, trigger])=>({emitter, trigger}),
    filter(x => x.trigger !== false),
    map(x => x.emitter)
);

// and when you wanted to start emitting:
watchMe$.subscribe(console.log)
emitter$.next(2);
emitter$.next(3);
trigger.next(true); // console.log: 3
emitter$.next(4); // console.log: 4

Leave a Reply

(*) Required, Your email will not be published