the following is an extension to observable to provide a safeSubscribe
method that results in a subscription that each component's onDestroy
method automatically unsubscribes.
// once _takeUntilDestroy$ on target emits, the subscription gets canceled
export function safeSubscribe<T>(target: any,
next?: (value: T) => void,
error?: (error: T) => void,
complete?: () => void): Subscription {
target._takeUntilDestroy$ = target._takeUntilDestroy$ || new Subject(); // our kill-switch for the subscription being defined
return this.pipe(
takeUntil(target._takeUntilDestroy$.asObservable()) // takeUntil enables the kill-switch
).subscribe(next, error, complete);
}
/**** add safeSubscribe to Observable ****/
(Observable as any).prototype.safeSubscribe = safeSubscribe;
declare module 'rxjs/internal/Observable' { // rxjs5 would be rxjs/Observable
export interface Observable<T> {
safeSubscribe: typeof safeSubscribe;
}
}
I have taken the merge declaration part from this SO.
This implementation works perfectly when subscribing to Angular HTTPClient requests, but it fails when I try to safeSubscribe
to observables created using factory methods like fromEvent
:
fromEvent(this.fileInput.nativeElement, 'change').safeSubscribe<any>(this, (x) => { console.log(x); });
yielding a safeSubscribe is not a function
error.
Am I extending Observable in the wrong way?
Output of npm list rxjs
+-- @angular-devkit/build-angular@0.6.3
| +-- @angular-devkit/architect@0.6.3
| | `-- rxjs@6.2.0 deduped
| +-- @angular-devkit/core@0.6.3
| | `-- rxjs@6.2.0 deduped
| `-- rxjs@6.2.0 deduped
+-- @angular/cli@6.0.3
| +-- @angular-devkit/schematics@0.6.3
| | `-- rxjs@6.2.0 deduped
| +-- @schematics/update@0.6.3
| | `-- rxjs@6.2.0 deduped
| `-- rxjs@6.2.0 deduped
`-- rxjs@6.2.0