Narek Gevorgyan
Narek Gevorgyan

Reputation: 123

Attempt to use a destroyed view: detectChanges event though the view is detached

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

Answers (1)

Pace
Pace

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

Related Questions