20

how do I properly escape the cancel button without throwing an error when using promises? My code throws an alert confirmation with a required checkbox. the code executes as it should to the user, but it throws an error in the console window:

Uncaught (in promise) cancel

//validation logic all passes...Now proceed to...

 else
    {

//determine and parse Discounts

 var myLookup = document.getElementsByName("myLookup")[0].value;
$.post( "findthem.php", {myLookup: myLookup })
  .done(function(json_data){
     var theResponse1 = $.parseJSON(json_data);
     myDiscountRate = theResponse1['ourDiscountFound'];

    }).then( function(callback){

    priceRate = priceRate * (1 - (.01 * myDiscountRate));
    newRate = priceRate.toFixed(2);
}

swal({
  title: "Confirm",
  input: 'checkbox',
  inputValue: 0,
  type: "warning",
  inputPlaceholder: 'I agree to <a href="#blahblahMore"></a> Your new Rate is :'+newRate,
  showCancelButton: true,
  confirmButtonText: 'Confirm',
  showLoaderOnConfirm: true,
  preConfirm: function(result) {
    return new Promise(function(resolve, reject) {
      if (result) {
        $.post("my.php", {
          Data: data
        })
        .done(
          function(json_data) {
            var data_array = $.parseJSON(json_data);
            var moreDetails = '';
            var resulting = 'error';
            var details = "Transaction Declined"
            if (data_array["trxApproved"] == true) {
              resulting = 'success';
              details = "Confirmed"
              moreDetails = "<br>Approved<b>" + data_array["approved"] + "</b>" +
                "<br>Details Code: <b>" + data_array["detailsCode"] + "</b>";
            }
            swal({
              type: resulting,
              title: details,
              html: "<h1>Details: </h1>" + data_array["messagetext"] + moreDetails
            });
          }
        );
        resolve();
      } else {
          reject('You must agree to our Terms & Conditions ');
      }
    });
  },
  allowOutsideClick: false
  }).then(function(json_data) {

  })
});
Limon Monte
  • 44,025
  • 43
  • 163
  • 189
Frankenmint
  • 1,304
  • 1
  • 15
  • 29
  • 3
    Hint: avoid the [Promise constructor antipattern](http://stackoverflow.com/q/23803743/1048572). – Bergi Sep 04 '16 at 21:27
  • Can you please indent your code properly? I can't discern where all those functions end. – Bergi Sep 04 '16 at 21:31
  • Thanks @guest271314 for the indentation. It looks like there's a closing `})` too much. Can you please post your full code? – Bergi Sep 04 '16 at 21:47
  • @Bergi I've tried to add in more code, but don't know how to do so without overcomplicating things, I need the promise there to handle my checkbox logic before pushing my form data to processing – Frankenmint Sep 04 '16 at 21:57
  • Thanks, though it appears there's still a `}` too much (after the `newRate` calculation). Alternatively you just could've removed the `})` in the end if the `then` call that it belongs to is of no concern for the question. – Bergi Sep 04 '16 at 22:00
  • @Frankenmint Do you have any docs about what the sweetalert callbacks do? Are you using one of the forks? – Bergi Sep 04 '16 at 22:12
  • 2
    @Bergi yes, I'm using https://limonte.github.io/sweetalert2, I can't seem to find within the docs how to cover 'cancel' on a confirmation using promises – Frankenmint Sep 04 '16 at 22:18
  • Thanks for the link, found it for you :-) – Bergi Sep 04 '16 at 22:28
  • Very Simple Solution : update your file and try to use updated **sweetalert.min.js** . i was facing same but after update i fix it. https://sweetalert.js.org/guides/#installation – pankaj kumar Dec 21 '20 at 09:25

5 Answers5

38

Update (Jan 2017): This issue has been fixed in v7: v7 upgrade guide ↗


You need to add a rejection handler to the Promise. Alternatively, you can use .catch(swal.noop) as a quick way to simply suppress the errors:

swal('...')
  .catch(swal.noop);

PS. the package you're using is called SweetAlert2, not SweetAlert. In future questions please mention it so you can get more relevant answers.

Limon Monte
  • 44,025
  • 43
  • 163
  • 189
  • 4
    thank you, changing my final (placeholder) `.then` to `.done` did the trick – Frankenmint Sep 04 '16 at 22:53
  • Uh, `done` is a horrible name for this method, it should've been called `ignoreDismissals` or something like that (assuming dismissals are the only cause for rejecting the promise). The `done` method does quite the opposite - throw unhandled rejections in the global context - in the `Q` promise library and many others inspired by it. – Bergi Sep 04 '16 at 23:00
  • 3
    @Bergi `.done()` [was replaced](https://github.com/limonte/sweetalert2/issues/324) by `.catch(swal.noop)`, thank you for your opinion. – Limon Monte Oct 31 '16 at 11:07
14

SweetAlert2 rejects the result promise when the cancel button is pressed. You can handle that:

swal({
  …
}).then(function(json_data) {
  …
}, function(dismiss) {
  if (dismiss === 'cancel') { // you might also handle 'close' or 'timer' if you used those
    // ignore
  } else {
    throw dismiss;
  }
})

If you don't need to do anything with the json_data, you might also use the catch method.

Limon Monte
  • 44,025
  • 43
  • 163
  • 189
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
4

new Promise(function(resolve, reject) { is not necessary. $.post() returns a jQuery promise object.

Possible solution substitutes Promise.reject() for new Promise() constructor; removed .then() that was placed as an option to first swal() call; pattern appears to expect a Promise to be returned from preConfirm, though not certain what value is expected to be returned from .done() other than json_data.

swal({
  title: "Confirm",
  input: 'checkbox',
  inputValue: 0,
  type: "warning",
  inputPlaceholder: 'I agree to <a href="#blahblahMore"></a>',
  showCancelButton: true,
  confirmButtonText: 'Confirm',
  showLoaderOnConfirm: true,
  preConfirm: function(result) {
      if (result) {
        return $.post("my.php", {
          Data: data
        })
        .done(
          function(json_data) {
            var data_array = $.parseJSON(json_data);
            var moreDetails = '';
            var resulting = 'error';
            var details = "Transaction Declined"
            if (data_array["trxApproved"] == true) {
              resulting = 'success';
              details = "Confirmed"
              moreDetails = "<br>Approved<b>" + data_array["approved"] + "</b>" +
                "<br>Details Code: <b>" + data_array["detailsCode"] + "</b>";
            }
            swal({
              type: resulting,
              title: details,
              html: "<h1>Details: </h1>" + data_array["messagetext"] + moreDetails
            });
          }
        );
      } else {
          return Promise.reject('You must agree to our Terms & Conditions ');
      }
  },
  allowOutsideClick: false
});
guest271314
  • 1
  • 10
  • 82
  • 156
  • How does this solve the problem of the uncaught rejection? – Bergi Sep 04 '16 at 21:31
  • Your last sentence should probably be a comment, not an answer. – Bergi Sep 04 '16 at 21:32
  • @Bergi _"How does this solve the problem of the uncaught rejection?"_ First by suggesting to remove unnecessary `Promise` constructor. _"Your last sentence should probably be a comment, not an answer."_ Not certain if the error is due to uncaught undefined `result`? Will take a minute to sort out rearranging `$.post()`, `.done()`, `.then()` and to check for other possible errors. – guest271314 Sep 04 '16 at 21:39
  • So your "solution" is to remove native promises because jQuery doesn't track unhandled rejections, instead of fixing the root cause!? – Bergi Sep 04 '16 at 21:44
  • @Bergi _"So your "solution" is to remove native promises because jQuery doesn't track unhandled rejections, instead of fixing the root cause!?"_ How did you draw that conclusion? Only stated that `Promise` constructor was not necessary. Still reviewing `javascript`; there is an `.then()` that is defined as an option of call to `swal` instead of being chained to `.done()`. Presently rearranging `javascript` from orginal Question. Noticed `result` is defined – guest271314 Sep 04 '16 at 21:48
  • If all you wanted to state was that the `Promise` constructor is not necessary in the code (which is correct), without solving the problem of the question, you should've posted a comment not an answer. I drew the conclusion because usually answers try to answer the question, which yours currently doesn't. – Bergi Sep 04 '16 at 21:51
  • @Bergi _"If all you wanted to state the Promise constructor is not necessary in the code, without solving the problem of the question, you should've posted a comment, not an answer."_ What are you talking about? Of course will try to correct issues with existing `javascript`. Have mentioned in above comments was checking for other possible errors. Will post possible solution in a few seconds – guest271314 Sep 04 '16 at 21:53
  • You just should wait with posting an answer until you have found the actual error. – Bergi Sep 04 '16 at 21:54
  • 1
    Regarding "*`// return ?`*": No, you can't `return` from a `done` callback. If it was a `then` callback it might make sense. – Bergi Sep 04 '16 at 21:56
  • @Bergi _"You just should wait with posting an answer until you have found the actual error."_ Really? With all due respect, that is out of line. Are you really going to advise another user when and how to post an Answer to a Question? As if you have not edited any of your own Answers? _"No, you can't return from a done callback. If it was a then callback it might make sense."_ Yes, avoid using `.done()`, here, except to pass an array of functions to call. See updated post – guest271314 Sep 04 '16 at 22:03
  • @Bergi Removed reference to possible `return` at `.done()` – guest271314 Sep 04 '16 at 22:11
  • 1
    You asked for a "downvote description", so I explained it. Answers should be self-contained, they are not a communication medium (like comments). They should answer the question from the first posted version. I felt your post did not contain a solution to the problem, so I used the "not useful" button. – Bergi Sep 04 '16 at 22:18
  • @Bergi Fair enough. Though _"They should answer the question from the first posted version."_ is difficult to consistently and practically achieve; user may add requirements at Question or comments, Answer could be improved by user that posts Answer. There would be no edited Answers at SO if this was adhered to. Still not sure where error is generated? Unless `allowOutsideClick: false }).then(function(json_data) { })` generated the error? – guest271314 Sep 04 '16 at 22:24
3

you will need to catch the action for cancel

swal({
  title: 'Are you sure?',
  text: "You won't be able to revert this!",
  type: 'warning',
  showCancelButton: true,
  confirmButtonColor: '#3085d6',
  cancelButtonColor: '#d33',
  confirmButtonText: 'Yes, delete it!'
}).then(function(json_data) {
  //delete item
}, function(dismiss) {
  if (dismiss === 'cancel' || dismiss === 'close') {
    // ignore
  } 
})
Adeojo Emmanuel IMM
  • 1,702
  • 1
  • 14
  • 25
3

Adding catch(swal.noop); at the end swal function will solve this problem

For example:

swal({

}).then(function() {

}).catch(swal.noop);
kishore ms
  • 55
  • 7