I have the following component that creates an MdDialog
export class SideNavsComponent implements OnInit, AfterViewInit, OnDestroy {
eventDispatcher: EventDispatcher
authEmailDialogRef: MdDialogRef<AuthEmailDialogComponent>
constructor(public dialog: MdDialog,) {
this.eventDispatcher = new EventDispatcher()
}
signIn( event ): void {
this.isSignedIn = event.checked
this.openDialog()
}
openDialog() {
this.authEmailDialogRef = this.dialog.open( AuthEmailDialogComponent, {
height: '500px',
width: '300px',
disableClose: true
} )
}
ngOnDestroy() {
}
ngAfterViewInit() {
}
ngOnInit() {
event_dispatcher.on( 'CLOSE authEmailDialogRef', ( target: Object ) => {
this.authEmailDialogRef.close()
} )
}
}
The component below creates a button that when clicked closes the MdDialog created above by sending and event that is intercepted within the SideNavsComponent#ngOnInit method
export class AuthEmailDialogComponent implements OnInit {
eventDispatcher: EventDispatcher = new EventDispatcher()
}
cancel() {
event_dispatcher.dispatch( 'CLOSE authEmailDialogRef', '')
}
}
The MdDialog is closed(), but a detection change error always occurs with the following:
ERROR Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges
at viewDestroyedError (core.es5.js:8636)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:12781)
at checkAndUpdateView (core.es5.js:12122)
at callWithDebugContext (core.es5.js:13184)
at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.es5.js:12724)
at ViewRef_.detectChanges (core.es5.js:10196)
at asterisk.component.ts:37
at ZoneDelegate.webpackJsonp.1467.ZoneDelegate.invokeTask (zone.js:414)
at Object.onInvokeTask (core.es5.js:4119)
at ZoneDelegate.webpackJsonp.1467.ZoneDelegate.invokeTask (zone.js:413)
View_MdDialogContainer_Host_0 @ MdDialogContainer_Host.html:1
proxyClass @ compiler.es5.js:14091
DebugContext_.logError @ core.es5.js:13124
ErrorHandler.handleError @ core.es5.js:1144
next @ core.es5.js:4757
schedulerFn @ core.es5.js:3830
SafeSubscriber.__tryOrUnsub @ Subscriber.js:236
SafeSubscriber.next @ Subscriber.js:185
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3816
NgZone.triggerError @ core.es5.js:4188
onHandleError @ core.es5.js:4149
webpackJsonp.1467.ZoneDelegate.handleError @ zone.js:385
webpackJsonp.1467.Zone.runTask @ zone.js:184
ZoneTask.invoke @ zone.js:476
timer @ zone.js:1491
setInterval (async)
scheduleTask @ zone.js:1501
webpackJsonp.1467.ZoneDelegate.scheduleTask @ zone.js:400
onScheduleTask @ zone.js:290
webpackJsonp.1467.ZoneDelegate.scheduleTask @ zone.js:394
webpackJsonp.1467.Zone.scheduleTask @ zone.js:225
webpackJsonp.1467.Zone.scheduleMacroTask @ zone.js:248
(anonymous) @ zone.js:1527
proto.(anonymous function) @ zone.js:1402
AsteriskComponent @ asterisk.component.ts:37
createClass @ core.es5.js:10870
createDirectiveInstance @ core.es5.js:10701
createViewNodes @ core.es5.js:12064
callViewAction @ core.es5.js:12508
execComponentViewsAction @ core.es5.js:12417
createViewNodes @ core.es5.js:12091
createRootView @ core.es5.js:11969
callWithDebugContext @ core.es5.js:13184
debugCreateRootView @ core.es5.js:12644
ComponentFactory_.create @ core.es5.js:9890
ComponentFactoryBoundToModule.create @ core.es5.js:3427
ViewContainerRef_.createComponent @ core.es5.js:10092
PortalHostDirective.attachComponentPortal @ material.es5.js:2135
MdDialogContainer.attachComponentPortal @ material.es5.js:19218
MdDialog._attachDialogContent @ material.es5.js:19486
MdDialog.open @ material.es5.js:19400
webpackJsonp.751.SideNavsComponent.openDialog @ side-navs.component.ts:39
webpackJsonp.751.SideNavsComponent.signIn @ side-navs.component.ts:35
(anonymous) @ SideNavsComponent.html:32
handleEvent @ core.es5.js:11892
callWithDebugContext @ core.es5.js:13184
debugHandleEvent @ core.es5.js:12772
dispatchEvent @ core.es5.js:8792
(anonymous) @ core.es5.js:10720
schedulerFn @ core.es5.js:3842
SafeSubscriber.__tryOrUnsub @ Subscriber.js:236
SafeSubscriber.next @ Subscriber.js:185
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3816
ToggleButton.toggle @ togglebutton.js:42
(anonymous) @ ToggleButton.html:4
handleEvent @ core.es5.js:11892
callWithDebugContext @ core.es5.js:13184
debugHandleEvent @ core.es5.js:12772
dispatchEvent @ core.es5.js:8792
(anonymous) @ core.es5.js:9384
(anonymous) @ platform-browser.es5.js:2683
webpackJsonp.1467.ZoneDelegate.invokeTask @ zone.js:414
onInvokeTask @ core.es5.js:4119
webpackJsonp.1467.ZoneDelegate.invokeTask @ zone.js:413
webpackJsonp.1467.Zone.runTask @ zone.js:181
ZoneTask.invoke @ zone.js:476
MdDialogContainer_Host.html:1 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 0, nodeDef: {…}, elDef: {…}, elView: {…}}
How can I prevent the changeDetection firing after the component is destroyed; in otherwords how can I make this code work without the error?
NB: Tried many suggestions on stackoverflow but none worked.
Thanks
Padegal Saigiriraj is right. But instead of ViewRef_
use ViewRef
. In short:
setTimeout(() => {
if (this.cdr && !(this.cdr as ViewRef).destroyed) {
this.cdr.detectChanges();
}
});
ViewRef stands for Angular view, specifically the host view as Angular site describes.
The issue is the close action of the dialog is removing the item from the view, and your EventDispatcher IS NOT AN ANGULAR METHOD so it fires outside the zone context and freaks it out. It goes like this:
You can either use a different method to communicate with the dialog, or switch to onPush() for change detection
I suggest you Use the afterClosed
handle instead:
this. authEmailDialogRef.afterClosed().subscribe(result => {
console.log(`Dialog result: ${result}`); // Pizza!
});
I pulled that snippet straight from the docs: HERE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With