I’m writing some code that uses fromEventPattern
to subscribe/unsubscribe to a third party event handler.
It should:
- Subscribe on a user action – multiple subscriptions are allowed
- When a certain condition is met a function is called to complete the observable
- Any further attempts to re-subscribe should do nothing
Caveat: in the example code i’m using document click with fromEventPattern
for demonstration purposes only
In the demo do the following:
- Open the browser console
- Click the Subscribe button (as many times as you like)
- Click anywhere in the preview pane
- Click the Complete button
Attempted Solution
function addClickHandler(handler: (event: MouseEvent) => void) {
console.log('added click handler');
document.addEventListener('click', handler);
}
function removeClickHandler(handler: (event: MouseEvent) => void) {
console.log('removed click handler');
document.removeEventListener('click', handler);
}
const click$ = fromEventPattern(addClickHandler, removeClickHandler);
const destroy = new Subject();
const destroy$ = destroy.asObservable();
const outer = new BehaviorSubject<MouseEvent | undefined>(undefined);
const outer$ = outer.asObservable().pipe(
switchMap(() => click$),
takeUntil(destroy$),
share()
);
function subscribe() {
outer$.subscribe({
next: console.log,
complete: () => console.log('completed'),
});
}
function unsubscribe() {
destroy.next(true);
destroy.complete();
outer.complete();
}
Question
The solution works but i get the feeling there’s probably a more succinct/better way to solve this without the need for a BehaviourSubject
and having to complete both the destroy
and outer
Observable.
Any ideas?