Skip to content

Instantly share code, notes, and snippets.

@diamond-darrell
Created May 29, 2019 13:50
Show Gist options
  • Save diamond-darrell/1cfb3080303309cbea7021c9c7234c1a to your computer and use it in GitHub Desktop.
Save diamond-darrell/1cfb3080303309cbea7021c9c7234c1a to your computer and use it in GitHub Desktop.
import {merge, MonoTypeOperatorFunction, Observable, Operator, Subject, Subscriber, TeardownLogic} from "rxjs";
import {OnDestroy} from "@angular/core";
const __ngOnDestroySource__ = Symbol("__ngOnDestroySource__");
const __ngOnDestroy__ = Symbol("__ngOnDestroy__");
interface EnhancedOnDestroy extends OnDestroy {
[__ngOnDestroySource__]: Subject<string>;
[__ngOnDestroy__]: () => void;
}
export function cancelOnDestroy<T>(instance: OnDestroy,
manualDestroy?: Observable<any>): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) => source.lift(new CancelOnDestroyOperator(instance, manualDestroy));
}
class CancelOnDestroyOperator<T> implements Operator<T, T> {
constructor(private instance: OnDestroy, private manualDestroy?: Observable<any>) {
if (instance.ngOnDestroy) {
if (!(<EnhancedOnDestroy>instance)[__ngOnDestroySource__]) {
(<EnhancedOnDestroy>instance)[__ngOnDestroySource__] = new Subject();
(<EnhancedOnDestroy>instance)[__ngOnDestroy__] = instance.ngOnDestroy;
instance.ngOnDestroy = function (this: EnhancedOnDestroy) {
this[__ngOnDestroy__].apply(this, arguments);
this[__ngOnDestroySource__].next();
this[__ngOnDestroySource__].complete();
};
}
}
}
call(subscriber: Subscriber<T>, source: any): TeardownLogic {
return source.subscribe(new CancelOnDestroySubscriber(subscriber, <EnhancedOnDestroy>this.instance, this.manualDestroy));
}
}
class CancelOnDestroySubscriber<T> extends Subscriber<T> {
constructor(destination: Subscriber<T>,
private _instance: EnhancedOnDestroy,
private manualDestroy?: Observable<any>) {
super(destination);
const sources = manualDestroy
? merge(manualDestroy, _instance[__ngOnDestroySource__])
: _instance[__ngOnDestroySource__].asObservable();
this.add(sources.subscribe(
() => {
destination.unsubscribe();
}
));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment