Yogeshwar Pullagurla
Yogeshwar Pullagurla

Reputation: 23

Invoke method when no observers for RxJs Subject

How to invoke a method when all the observers have unsubscribed from a subject.

Update

const alphaStore = new BehaviourSubject(0);
observer1 = alphaStore.subscribe(console.log);
observer2 = alphaStore.subscribe(console.log);

And when all of these observers unsubscribe. I want a method to be invoked. Like...

Observer1 unsubscribed

Observer2 unsubscribed

All observers left

Upvotes: 2

Views: 504

Answers (2)

martin
martin

Reputation: 96969

What you describe already does the finalize() operator. Better said finalize() calls its callback when the chain disposes which means it's called when all observers unsubscribes, the chain completes or errors.

const subject = new Subject();
const shared = subject.pipe(
  finalize(() => console.log('finalize')),
  share(),
);

https://stackblitz.com/edit/rxjs-rebfba

When all observers unsubscribe share() unsubscribes from its source which triggers finalize().

Currently there's no way to distinguish why finalize() was invoked. See this issue https://github.com/ReactiveX/rxjs/issues/2823 and examples there on how to do it.

Upvotes: 1

kos
kos

Reputation: 5364

You can create a custom Observable, that will track the subscription count.

Heres a simple example:

let count = 0;

const tracked$ = new Observable(() => {
  count++;

  return ()=>{
    count--;
    if (count === 0) {
      console.log('I am empty');
    }
  };
})

And then merge it with Observable that does actual work. For simplicity sake, lets imagine its just a timer

// const tracked$ = ...

const data$ = Observable.timer(0, 5);

const result$ = data$
  .merge(tracked$)
  .take(5)
  .subscribe(value => console.log('v:', value));

After 5 values were emitted -- it will log I am empty.

Heres a live example (with some rewrite and two subscriptions):

https://observable-playground.github.io/gist/4a7415f3528aa125fb686204041138cb

NOTE: this code uses rxjs-compat notation, which is easier to read. Above linked example uses .pipe notation, which is more common now.

Hope this helps.

Upvotes: 0

Related Questions