shlomiassaf / ngx-modialog

Modal / Dialog for Angular
http://shlomiassaf.github.io/ngx-modialog
MIT License
686 stars 242 forks source link

Dialog was forced to close by an unknown source #284

Open web265p3 opened 7 years ago

web265p3 commented 7 years ago
Brdjx commented 7 years ago

I see this too. Not sure what it could be yet.

oislek commented 7 years ago

I am having the same issue. Any updates?

Brdjx commented 7 years ago

Not from my end.

jaklithn commented 7 years ago

I have same problem. My dialog bails out randomly now and then and makes the screen freeze with blocking modal dialog. Impossible to use with this unpredictable behaviour ....

EXCEPTION: Uncaught (in promise): Error: Dialog was forced to close by an unknown source.
Error: Dialog was forced to close by an unknown source.
    at new DialogBailOutError (http://localhost/MyApp/libs/angular2-modal/bundles/angular2-modal.umd.js:340:32)
    at DialogRef.bailOut (http://localhost/MyApp/libs/angular2-modal/bundles/angular2-modal.umd.js:421:45)
    at ModalOverlay.exports.ModalOverlay.ModalOverlay.ngOnDestroy (http://localhost/MyApp/libs/angular2-modal/bundles/angular2-modal.umd.js:1208:32)

Any workaround or fix would be most appreciated!

brian-avery commented 7 years ago

So the problem here is that the dialog has a context that it was opened under on the current page. When you navigate away from that page, the context is lost, causing this error to occur.

I've got a simple workaround as well. Use a subscription to watch for navigation events. If you receive a close event and you want your dialog to stay open, redirect back to the current page. Make sure to call unsubscribe when the dialog closes otherwise you will always be redirected back to your current page.

myDialogWatcher = router.events.subscribe((event) => { router.navigate([this.router.url]) });

And then when you close your dialog, call: myDialogWatcher.unsubscribe();

jaklithn commented 7 years ago

I have now switched to nx-modal and made it work in my context, but thanks for your reply!

AsmaGargouri commented 7 years ago

I have the same issue. I didn't understand when it occures and when it doesn't. Any help ?

brian-avery commented 7 years ago

From https://github.com/shlomiassaf/angular2-modal/blob/master/src/lib/overlay/overlay.component.ts:

 ngOnDestroy(): void {
    super.ngOnDestroy();
    if (this.dialogRef.destroyed !== true) {
      // if we're here the overlay is destroyed by an external event that is not user invoked.
      // i.e: The user did no call dismiss or close and dialogRef.destroy() did not invoke.
      // this will happen when routing or killing an element containing a blocked overlay (ngIf)
      // we bail out, i.e gracefully shutting down.
      this.dialogRef.bailOut();
    }

The dialog belongs to the page that launched it. When the parent page changes, destroy is called on both the component that opened the dialog and the dialog itself. This leaves the dialog in an undefined state because the user has not called dialog.close() yet so there is no defined behavior of what to do with whatever content the dialog has. The current action is to throw an exception notifying that the dialog was closed by an unknown source.

My suggestion was to cancel the navigate while the dialog is open so that we don't encounter such undefined states. I did this by intercepting the navigate event generated by angular and using it to redirect back to the current page. This does cancel the user's ability to navigate while a dialog is open, but it means that the user doesn't lose any data present in the dialog.