ngx-modialog icon indicating copy to clipboard operation
ngx-modialog copied to clipboard

angular2-modal: EXCEPTION: Uncaught (in promise): undefined

Open kisdaniel opened this issue 8 years ago • 23 comments

I get the following error when I close the modal alert:

core.umd.js:6001 Error: Uncaught (in promise): undefined
    at resolvePromise (zone.js:418)
    at PromiseCompleter.reject (zone.js:395)
    at _dismiss (angular2-modal.umd.js:391)
    at eval (angular2-modal.umd.js:394)
    at ZoneDelegate.invoke (zone.js:192)
    at Object.onInvoke (core.umd.js:8772)
    at ZoneDelegate.invoke (zone.js:191)
    at Zone.run (zone.js:85)
    at zone.js:451
    at ZoneDelegate.invokeTask (zone.js:225)

Sample code:

       this.modal.alert()
            .size("lg")
            .showClose(true)
            .title("title")
            .body("message")
            .open();

Dependencies:

"dependencies": {
    "@angular/common": "2.0.0-rc.6",
    "@angular/compiler": "2.0.0-rc.6",
    "@angular/compiler-cli": "0.6.0",
    "@angular/core": "2.0.0-rc.6",
    "@angular/forms": "2.0.0-rc.6",
    "@angular/http": "2.0.0-rc.6",
    "@angular/platform-browser": "2.0.0-rc.6",
    "@angular/platform-browser-dynamic": "2.0.0-rc.6",
    "@angular/router": "3.0.0-rc.2",
    "@angular/upgrade": "2.0.0-rc.6",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.11",
    "systemjs": "0.19.27",
    "zone.js": "^0.6.17",
    "angular2-in-memory-web-api": "0.0.18",

    "angular2-modal": "^2.0.0-beta.10",
    "bootstrap": "^3.3.7",
    "font-awesome": "^4.6.3",
    "jquery": "^3.1.0",
    "momentjs": "^1.1.15",
    "ng2-translate": "^2.4.4"
  },

kisdaniel avatar Sep 13 '16 09:09 kisdaniel

+1 Also with RC6

Error: Uncaught (in promise): undefined at resolvePromise (polyfills.bundle.js:7870) at PromiseCompleter.reject (polyfills.bundle.js:7847) at _dismiss (main.bundle.js:1186) at main.bundle.js:1189 at ZoneDelegate.invoke (polyfills.bundle.js:7649) at Object.onInvoke (vendor.bundle.js:8934) at ZoneDelegate.invoke (polyfills.bundle.js:7648) at Zone.run (polyfills.bundle.js:7542) at polyfills.bundle.js:7903 at ZoneDelegate.invokeTask (polyfills.bundle.js:7682)

patriknil90 avatar Sep 13 '16 14:09 patriknil90

This exception is thrown when dismissing the dialog, if a reject function was not supplemented. The exception doesn't really cause any problems. But if you want to get rid of it, from a user perspective, you should make it like:

this.modal.alert().size("lg").showClose(true).title("title").body("message").open().then(result => { result.result.then(() => {}, () => {}); });

From the perspective of the library developer, @shlomiassaf could fix it by checking if the reject function actually exists before trying to call it.

AbdulRahmanAlHamali avatar Sep 15 '16 07:09 AbdulRahmanAlHamali

the workaround seems to be working by adding .then(result => { result.result.then(() => {}, () => {}); });.

I hope @shlomiassaf will fix it.

kisdaniel avatar Sep 15 '16 13:09 kisdaniel

I believe it's not possible to check if there is a reject handler for the promise.

A better approach would adding a context config for not rejecting the promise, although I understand that DialogRef shouldn't care about context properties. This means that all context would inherit from a BaseContext.

Paging @shlomiassaf for his view

JulioC avatar Sep 21 '16 01:09 JulioC

I think duplicates of #179 and #184.

andyrue avatar Sep 22 '16 01:09 andyrue

I'll look into a possible solution.

What about wrapping the resolve/reject call in a try/catch?

shlomiassaf avatar Sep 22 '16 23:09 shlomiassaf

AFAIK a try/catch wouldn't help with unhandled rejections, since they don't fire a exception on the .reject() call.

JulioC avatar Sep 22 '16 23:09 JulioC

Wouldn't it work if we just say:

if (reject !== undefined) reject();

What do you think?

On 23 Sep 2016 02:45, "Júlio César" [email protected] wrote:

AFAIK a try/catch wouldn't help with unhandled rejections, since they don't fire a exception on the .reject() call.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/shlomiassaf/angular2-modal/issues/188#issuecomment-249060004, or mute the thread https://github.com/notifications/unsubscribe-auth/AP4ByHCdyAmsDt-nIEOsLuUSHwb0Z82_ks5qsxL3gaJpZM4J7evY .

AbdulRahmanAlHamali avatar Sep 23 '16 04:09 AbdulRahmanAlHamali

What do you think about this?

if (typeof reject === "function") {
  reject();
}

kisdaniel avatar Sep 23 '16 07:09 kisdaniel

@kisdaniel this._resultDeferred.reject is always a function, the problem is due to the reason it does not have an handler, this a known Promise behaviour.

@JulioC You're completely right, I though the promise itself will throw and not the handlers inside, my bad.

I have another proposal, jus before rejecting register a catch handler.

      this.destroy();
      this._resultDeferred.promise.catch(() => {});
      this._resultDeferred.reject();

Usually this is wrong, the library shouldn't mess with the promise chain. However, I don't see any side effects here. Thinking Promises, the developer gets the promise object without any handlers, any handler (reject or resolve) that we add to the promise object is added as a ROOT handler so it doesn't effect any handlers registered by the developer.

Each handler from the ROOT is a different chain so I don't see any issues,

To illustrate:

Promise:
               then
                 then
                   catch
               catch
               catch // Catch registered by the library.

The last catch handler is the one registered by the library, all others will also fire, regardless. Anyway, if we get to this point the developer already registered all his handlers and anyway he has no way of adding more, at this point.

Thoughts?

shlomiassaf avatar Sep 23 '16 12:09 shlomiassaf

see the suggested PR

shlomiassaf avatar Sep 23 '16 13:09 shlomiassaf

I overlooked the fact that the promise could have any amount of catch handlers.

Your solution looks fine, as long this handler is only registered when the dialog is dismissed.

JulioC avatar Sep 23 '16 13:09 JulioC

I still get this when I close the modal (First time) error_handler.js:51 Error: Uncaught (in promise): undefined at resolvePromise (zone.js:418) at PromiseCompleter.reject (zone.js:395) at _dismiss (dialog-ref.js:65) at dialog-ref.js:68 at ZoneDelegate.invoke (zone.js:192) at Object.onInvoke (ng_zone_impl.js:43) at ZoneDelegate.invoke (zone.js:191) at Zone.run (zone.js:85) at zone.js:451 at ZoneDelegate.invokeTask (zone.js:225)

webartistkb avatar Oct 05 '16 22:10 webartistkb

Indeed, it will still throw if you set a resolve callback, but no reject:

modal.open(MyModal);
  .then(dialog => {});

I believe the only possible solution would stop rejecting the promise if the modal is dismissed.

Maybe add a DialogResult structure, which holds the close reason and data, but that means a breaking change...

JulioC avatar Oct 06 '16 17:10 JulioC

It would indeed be a very annoying breaking change because most people don't check the result in their Confirm dialogs. In addition the exception is not that problematic. It never caused any bugs for me at least, so I don't think it is worth a breaking change

AbdulRahmanAlHamali avatar Oct 06 '16 17:10 AbdulRahmanAlHamali

Hi guys, I am also getting this same error. Is there any work around without any breaking changes??

naveenprincep avatar Oct 12 '16 07:10 naveenprincep

You can still use the workaround above, always provide a reject callback:

modal.open(MyModal)
  .then(dialog => {})
  .catch(() => {}); // this is the workaround

JulioC avatar Oct 12 '16 15:10 JulioC

#223 fixed my issue. thanks

naveenprincep avatar Oct 13 '16 13:10 naveenprincep

This is still an issue. Angular 5.0.1 ngx-modialog 4.0.0-beta.3 zone.js 0.8.18

@JulioC workaround works

Romanchuk avatar Nov 15 '17 10:11 Romanchuk

same problem in angular 5.1.1

micheltank avatar Dec 25 '17 01:12 micheltank

I found the problem, need to pass the second param to "then":

dont works: dialog.result.then((result) => { console.log(result); });

works:

dialog.result.then((result) => { console.log(result); }, () => console.log('Rejected!'));

micheltank avatar Dec 25 '17 01:12 micheltank

@micheltank the second parameter is supposed to be optional.

dbrezoev avatar Feb 15 '18 16:02 dbrezoev

Hi please try to implement this way for dialog

this.modal.confirm()
      	.okBtn("Yes")
      	.cancelBtn("No")
      	.size('sm')
      	.showClose(true)
      	.title('Confirm')
      	.body("Do you want to accept?")
    	.open().then(result => {
       	result.result.then(result=> {
       		console.log('Yes');
       	},() =>
      		console.log('No!');
      	);
    });

bhattbhaskar avatar May 11 '18 13:05 bhattbhaskar