Cancelación no detectada (en promesa) usando SweetAlert2

5 minutos de lectura

avatar de usuario
menta

¿Cómo escapo correctamente el botón de cancelar sin arrojar un error al usar promesas? Mi código arroja una confirmación de alerta con una casilla de verificación requerida. el código se ejecuta como debería para el usuario, pero arroja un error en la ventana de la consola:

No atrapado (en promesa) cancelar

//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) {

  })
});

  • Sugerencia: evite el antipatrón del constructor Promise.

    – Bergi

    04/09/2016 a las 21:27

  • ¿Puedes sangrar tu código correctamente? No puedo discernir dónde terminan todas esas funciones.

    – Bergi

    04/09/2016 a las 21:31

  • Gracias @guest271314 por la sangría. Parece que hay un cierre }) demasiado. ¿Puedes publicar tu código completo?

    – Bergi

    4 sep 2016 a las 21:47

  • @Bergi Intenté agregar más código, pero no sé cómo hacerlo sin complicar demasiado las cosas, necesito la promesa allí para manejar la lógica de mi casilla de verificación antes de procesar los datos de mi formulario

    – menta

    04/09/2016 a las 21:57

  • @Bergi sí, estoy usando limonte.github.io/sweetalert2parece que no puedo encontrar en los documentos cómo cubrir ‘cancelar’ en una confirmación usando promesas

    – menta

    4 sep 2016 a las 22:18

avatar de usuario
limon monte

Actualización (enero de 2017): Este problema se ha solucionado en v7: guía de actualización v7 ↗


Debe agregar un controlador de rechazo a la Promesa. Como alternativa, puede utilizar .catch(swal.noop) como una forma rápida de simplemente suprimir los errores:

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

PD. el paquete que estás usando se llama SweetAlert2, no SweetAlert. En futuras preguntas, menciónelo para que pueda obtener respuestas más relevantes.

  • gracias, cambiando mi final (marcador de posición) .then a .done Hizo el truco

    – menta

    4 sep 2016 a las 22:53

  • Oh, done es un nombre horrible para este método, debería haberse llamado ignoreDismissals o algo así (suponiendo que los despidos sean la única causa para rechazar la promesa). los done El método hace todo lo contrario: lanzar rechazos no controlados en el contexto global, en el Q biblioteca promesa y muchas otras inspiradas en ella.

    – Bergi

    04/09/2016 a las 23:00

  • @Bergi .done() fue remplazado por .catch(swal.noop)Gracias por tu opinión.

    – Limón Monte

    31 de octubre de 2016 a las 11:07

avatar de usuario
Bergi

SweetAlert2 rechaza la promesa de resultado cuando se presiona el botón cancelar. Puedes maneja eso:

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;
  }
})

Si no necesita hacer nada con el json_datatambién puede utilizar el catch método.

  • Es SweetAlert2 🙂 SweetAlert original no es compatible desde hace 11 meses.

    – Limón Monte

    04/09/2016 a las 22:45

  • SweetAlert2 no rechaza promesas de forma predeterminada a partir de v7: github.com/sweetalert2/sweetalert2/releases/tag/v7.0.0

    – Limón Monte

    24 de enero de 2018 a las 8:37

avatar de usuario
invitado271314

new Promise(function(resolve, reject) { no es necesario. $.post() devuelve un objeto de promesa jQuery.

Posibles sustitutos de la solución Promise.reject() por new Promise() constructor; remoto .then() que se colocó como opción a primera swal() llamar; patrón parece esperar un Promise para ser devuelto de preConfirmaunque no estoy seguro de qué valor se espera que se devuelva de .done() otro que 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
});

  • ¿Cómo resuelve esto el problema del rechazo no detectado?

    – Bergi

    04/09/2016 a las 21:31

  • Su última oración probablemente debería ser un comentario, no una respuesta.

    – Bergi

    04/09/2016 a las 21:32

  • @Bergi “¿Cómo resuelve esto el problema del rechazo no detectado?” En primer lugar, sugiriendo que se eliminen Promise constructor. “Tu última oración probablemente debería ser un comentario, no una respuesta”. No estoy seguro si el error se debe a que no se detectó. result? Tomará un minuto resolver la reorganización $.post(), .done(), .then() y para comprobar otros posibles errores.

    – invitado271314

    04/09/2016 a las 21:39


  • Con respecto a “// return ?“: No, no puedes return a partir de una done llamar de vuelta. si fuera un then devolver la llamada podría tener sentido.

    – Bergi

    04/09/2016 a las 21:56

  • Usted pidió una “descripción de voto negativo”, así que lo expliqué. Las respuestas deben ser independientes, no son un medio de comunicación (como los comentarios). Deben responder a la pregunta de la primera versión publicada. Sentí que su publicación no contenía una solución al problema, así que usé el botón “no útil”.

    – Bergi

    4 sep 2016 a las 22:18

deberá capturar la acción para cancelar

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
  } 
})

avatar de usuario
inflar

Agregando catch(swal.noop); al final la función swal resolverá este problema

Por ejemplo:

swal({

}).then(function() {

}).catch(swal.noop);

¿Ha sido útil esta solución?