javascriptrxjsreplaysubject

Make a ReplaySubject return only the last value on subscribe


I have a strange use case where I need to keep track of all previous emitted events.

Thanks to the ReplaySubject, it works perfectly so far. On every new subscriber, this Subject re-emits every previous events.

Now, for a specific scenario, I need to be able to give only the latest published events (a bit like a BehaviorSubject), but keeping the source the same events.

Here is a snippet of what I'm trying to achieve: stackblitz

import { ReplaySubject, BehaviorSubject, from } from "rxjs";

class EventManager {
  constructor() {
    this.mySubject = new ReplaySubject();
  }

  publish(value) {
    this.mySubject.next(value);
  }

  fullSubscribe(next, error, complete) {
    return this.mySubject.subscribe(next, error, complete);
  }

  subscribe(next, error, complete) {
    return this.mySubject.pipe(/* an operator to get the last one on new subscribe */).subscribe(next, error, complete);
  }
}

const myEventManager = new EventManager();

myEventManager.publish("Data 1");
myEventManager.publish("Data 2");
myEventManager.publish("Data 3");

myEventManager.fullSubscribe(v => {
  console.log("SUB 1", v);
});

myEventManager.subscribe(v => {
  console.log("SUB 2", v);
});

Thank you


Solution

  • If you keep track of the number of events you've published, you could use skip:

      subscribe(next, error?, complete?) {
        return this.mySubject.pipe(
          skip(this.publishCount - 1)
        ).subscribe(next, error, complete);
      }
    

    Here's a StackBlitz demo.