Reputation: 123
I have a component which does some service calls, and gets promises. After Promises are resolved I am doing detectChanges. But sometimes the promises are being resolved when the component view is already destroyed, eg user closed tab (internal tab of our app). In that case I am getting
ViewDestroyedError: Attempt to use a destroyed view: detectChanges
. Even though I have detached the view on destroy phase of my tab.component. My question is what am I doing wrong here?
I have tried to detach the view from change detection on destroy phase with no luck, promise is being resolved after destroy phase and detectChanges is still called. I do understand that ngOnDestroy is not actually destroying the class and that the code inside of it will be destroyed on garbage collection phase.
here is an example code from my tab.component that causes the issue
const promises:Promise<any>[] = [];
_.each(types, (type:string) => {
promises.push(this.service.getResultsBy(type))
})
Promise.all(promises)
.then((data) => {
//some code here
this.cd.detectChanges();
})
and in ngOnDestroy
I am detaching the view from C.D
ngOnDestroy() {
this.cd.detach();
}
The promises are important for me in this case, cause I do need to do some calculations/state saving even if the component is destroyed. I just want to understand how can I detach the view good enough so that my code inside the promise will not cause change detection attempts.
Upvotes: 4
Views: 7123
Reputation: 43867
Detaching from change detection on ngOnDestroy
is not needed and will not help with this error. However, you cannot call detectChanges
after ngOnDestroy
has been called. With observables you can unsubscribe from the observable in ngOnDestroy
. There is no way to unsubscribe from a Promise
so you will need to keep a flag in your component instead.
export class MyComponent {
private destroyed = false;
ngOnDestroy() {
this.destroyed = true;
}
triggerChangeDetection() {
if (!this.destroyed) {
this.cd.detectChanges();
}
}
}
Upvotes: 3