Reputation: 6403
A private (but open source) Angular package in the organisation I work for has some code that looks like this:
ngAfterViewInit(): void {
setTimeout(() => {
this.changeDetector.detectChanges();
// do more things
});
}
We implement this package in our application (the package is to introduce common components so that front-end devs across the org don't implement things multiple times, and to enforce a common design language for consistency). However, when using the component this is called in, and showing and then destroying the component repeatedly, eventually it will stop working, with this error in the console:
Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges
I'm trying to find a way of making sure the code above is not being run if the component has already been destroyed. I have considered using the ngOnDestroy
lifecycle method:
ngOnDestroy(): void {
this.changeDetector.detach();
}
but I'm not sure what else I would put in there to check the view is ok. I also thought about something like:
if (!this.changeDetector.destroyed) {
this.changeDetector.detectChanges();
}
but nothing like destroyed
exists on ChangeDetectorRef
.
What is the correct way of ensuring this error does not show and the component works, even when repeatedly showing and destroying it?
Upvotes: 3
Views: 8099
Reputation: 6403
I think the best solution I have found is to use !ViewRef.destroyed
and if that returns truthy then proceed, otherwise don't.
if (!(this.changeDetector as ViewRef).destroyed) {
this.changeDetector.detectChanges()
// do other tasks
}
Upvotes: 19
Reputation: 2225
I think destroyed does work but the syntax is like this:
if (!this.changeDetector['destroyed']) {
this.changeDetector.detectChanges();
}
Then obviously, just keep the code you have on your ngOnDestroy hook.
Upvotes: 3