Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 - Uncaught Attempt to use a destroyed view: detectChanges

So my application keeps giving me this error:

extensions::uncaught_exception_handler:8 Error in event handler for runtime.onMessage: Attempt to use a destroyed view: detectChanges
at ViewDestroyedException.BaseException [as constructor] (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:3776:27)
at new ViewDestroyedException (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:6957:20)
at DebugAppView.AppView.throwDestroyedError (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:10041:76)
at DebugAppView.AppView.detectChanges (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:9994:22)
at DebugAppView.detectChanges (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:10084:48)
at ViewRef_.detectChanges (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/@angular/core/core.umd.js:9397:69)
at SafeSubscriber.eval [as _next] (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/scripts/components/product-card.component.js:63:54)
at SafeSubscriber.__tryOrUnsub (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1408:16)
at SafeSubscriber.next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1357:22)
at Subscriber._next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1307:26)
at Subscriber.next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1271:18)
at Subject._finalNext (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1063:30)
at Subject._next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1055:18)
at Subject.next (chrome-extension://npblbblmbmcjbldhcneoocaobkkicbno/node_modules/rxjs/Subject/../bundles/Rx.umd.js:1012:14)handler @ extensions::uncaught_exception_handler:8(anonymous function) @ extensions::uncaught_exception_handler:100EventImpl.dispatch_ @ extensions::event_bindings:376EventImpl.dispatch @ extensions::event_bindings:393target.(anonymous function) @ extensions::SafeBuiltins:19publicClass.(anonymous function) @ extensions::utils:94messageListener @ extensions::messaging:189target.(anonymous function) @ extensions::SafeBuiltins:19EventImpl.dispatchToListener @ extensions::event_bindings:387target.(anonymous function) @ extensions::SafeBuiltins:19publicClass.(anonymous function) @ extensions::utils:94EventImpl.dispatch_ @ extensions::event_bindings:371EventImpl.dispatch @ extensions::event_bindings:393target.(anonymous function) @ extensions::SafeBuiltins:19publicClass.(anonymous function) @ extensions::utils:94dispatchOnMessage @ extensions::messaging:320

Upon calling detectChanges on a component's ChangeDetectorReference: this._changeDetectorRef.detectChanges();

I came across a similar stack over question:

What is a dehydrated detector and how am I using one here?

and some github issues:

https://github.com/angular/angular/issues/6786 https://github.com/angular/angular/issues/6786#issuecomment-185429140

That led me to call detectChanges as such:

setTimeout( () => this._changeDetectorRef.detectChanges(), 10);

Which changed the error to this:

zone.js:260 Uncaught Attempt to use a destroyed view: detectChanges
Zone.runTask @ zone.js:260
ZoneTask.invoke @ zone.js:423

But it is still happening. It is not breaking my application (it was before using setTimeout), but I would like to figure out how to get rid of it.

I'm calling detectChanges() because there are things happening in the background that change the state of the application (not the result of user input). The component is not newly created or about to be destroyed when detectChanges() is called. The component's style changes as a result of something that happens in the background.

like image 299
Gabe O'Leary Avatar asked May 23 '16 20:05

Gabe O'Leary


Video Answer


2 Answers

In the constructor of your class to give:

setTimeout( () => this._changeDetectorRef.markForCheck(), 10);

And in @component:

changeDetection: ChangeDetectionStrategy.OnPush,
like image 84
Emerceen Avatar answered Oct 12 '22 16:10

Emerceen


My errors were being thrown because of a subscribe() trying to execute its completion code after the view had already changed.

...
.then(response => {
    ...
    scope.cdr.detectChanges();
});
...

This would happen if I switched the view very quickly or the internet was slow.


I created a boolean when the view is created and set to true:

view_active: Boolean = true

then when the view is destroyed set it to false:

ngOnDestroy() {
    this.view_active = false
}

and then check against that before calling detectChanges()

...
.then(response => {
    ...
    if(scope.view_active) {
        scope.cdr.detectChanges();
    }
});
...
like image 31
theblindprophet Avatar answered Oct 12 '22 16:10

theblindprophet