After upgrading my app to Angular 12, I'm getting this strange error message whenever I navigate away from a component of which the ngOnDestroy function contains .unsubscribe()
calls. Even more strange, that teardown.unsubscribe
isn't mentioned in my project whatsoever, making debugging very difficult.
ERROR Error: Uncaught (in promise): UnsubscriptionError: 1 errors occurred during unsubscription:
1) TypeError: teardown.unsubscribe is not a function
Error
at _super (createErrorClass.js:4)
at new UnsubscriptionErrorImpl (UnsubscriptionError.js:3)
at SafeSubscriber.unsubscribe (Subscription.js:55)
at SafeSubscriber.unsubscribe (Subscriber.js:55)
at FooComponent.ngOnDestroy (my-foo.component.ts:58)
at executeOnDestroys (core.js:7406)
at cleanUpView (core.js:7309)
at destroyViewTree (core.js:7142)
at destroyLView (core.js:7287)
at RootViewRef.destroy (core.js:22651)
at resolvePromise (zone.js:1213)
at resolvePromise (zone.js:1167)
at zone.js:1279
at ZoneDelegate.invokeTask (zone.js:406)
at Object.onInvokeTask (core.js:28667)
at ZoneDelegate.invokeTask (zone.js:405)
at Zone.runTask (zone.js:178)
at drainMicroTaskQueue (zone.js:582)
at ZoneTask.invokeTask [as invoke] (zone.js:491)
at invokeTask (zone.js:1600)
my-foo.component.ts
57: ngOnDestroy(): void {
58: this.aSubscription$?.unsubscribe();
59: this.bSubscription$?.unsubscribe();
60: this.cSubscription$?.unsubscribe();
61: this.dSubscription$?.unsubscribe();
62: }
CodePudding user response:
If you are suscribing like this
aSubscription_instance = this.aSubscription$.subscribe(() => {
/// Code here
});
then in the ngOnDestroy() write
aSubscription_instance && aSubscription_instance.unsubscribe()
CodePudding user response:
I really recommend the following pattern on subscriptions:
export class AComponent{
subscriptions = new Subscription();
//subscribing
ngOnInit(){
this.subscriptions.add(
this.aService.subscribe(...)
);
this.subscriptions.add(
this.bService.subscribe(...)
)
}
//unsubscribing
ngOnDestroy(){
subscriptions.unsubscribe();
}
}
This way you won't get errors, because rcjs Subscriptions are unsubscribed safely, you won't get errors even though no subscriptions are present.
CodePudding user response:
TBH none of these patterns are good. This is the best approach:
private unsubscribe$: Subject<any> = new Subject()
ngOnInit() {
this.myService.pipe(takeUntil(this.unsubscribe$)).subscribe()
}
ngOnDestroy() {
this.unsubscribe$.next()
this.unsubscribe$.complete()
}
NOTE: .pipe(takeUntil(this.unsubscribe$))
does the unsubscribe - just add this for every sub - less boiler plate code. Use this approach and your problems will vanish away ...