1
votes

Let's say I have an interval that each second sends an heartbeat. At each beat i'd like to inspect something on my web page and react accordingly. I'd also like the option to unsubscribe from the inner Observables actions, but keep getting the heartbeat so when i subscribe back, everything will flow as before. Creating a Subscription from Interval and piping it leaves no option to unsubscribe from the inner action, but only the whole subscription as whole. Is there a way to return the inner Observable so i can unsubscribe from it while still retaining the heartbeat created from the Interval?

Edit: I've tried to create a class to describe what I'm talking about:

class Monitor {
    sub: Subscription | null = null;

    start() {
        this.sub = this.monitor().subscribe();
    }

    monitor() {
        const dom$ = someSelectorObserver(this.win.document, '#someSelector').pipe(
            mergeMap(newElementOrBail => {
                if (newElementOrBail) {
                    return handle(newElementOrBail);
                } else {
                    return bail();
                }
            }),
            tap({
                error: error => this.log.error(error),
            }),
        );

        return dom$;
    }

    handle(ele: HTMLElement) {
        // do stuff
    }

    bail() {
        this.sub.unsubscribe();
    }
}

So basically my monitor starts with creating the subscription, as long as there's a new element to handle everything is fine, but when a bail signal appears I'd like to unsubscribe while still monitoring the DOM changes for a return of the previous elements. So the outer subscription is basically the DOM observer and the inner is the mergeMap handle function. Does it make more sense?

2

2 Answers

0
votes

You could just put some conditional on your inner observable:

private takeSignal = true
interval(3000).pipe(switchMap(() => takeSignal ? inner$ : NEVER))

Then just flip takeSignal as needed.

But it seems easier to just unsubscribe from the whole thing and resubscribe when needed. Why keep the interval going when you’re not using it?

0
votes

You can split your logic in two (or more) streams.

Store heartbeat$ in a separate variable and subscribe to multiple times for different reasons.

In this way, you'd be able to split your logic into different streams and control subscriptions individually.

const heartbeat$ = interval(3000);

const inspectWeb = heartbeat$.pipe(
  // do stuff
).subscribe()

inspectWeb.unsubscribe()


heartbeat$.pipe(
  // do other stuff
).subscribe()