Forma correcta de cerrar un modal de Bootstrap al terminar un AJAX

Si estás intentando cerrar el modal de la siguiente manera, ten por seguro que NO FUNCIONARÁ:

…;
$('#modalBox).modal('show');

$.ajax({
  …,
  …,
}).done(function(response){
  $('#modalBox').modal('hide');
  …;
  …;
}).fail(function(){
  //
});

EL PROBLEMA

El problema reside en que para que un modal se muestre (show), necesita algo de tiempo (milisegundos) para realizar todas las transiciones necesarias, tanto en javascript, como en css. Entonces, si se ejecuta un AJAX de inmediato, se detendrá la secuencia y solo se podrá retomar una vez que el AJAX esté completamente procesado, debido a que tiene preferencia sobre otras instrucciones y animaciones.

Una vez que el AJAX ha terminado, inmediatamente se ejecuta el método “done()”, donde se encuentra la instrucción de cierre del modal (hide), que se ejecuta sin que estuviera retomada y terminada la transición de apertura (show), por lo que el modal no se cerrará.

Una alternativa que he visto en algunos sitios de tecnología web, consiste en agregar un retraso de tiempo para la ejecución de la instrucción de cierre (‘hide’), pero considero que no es la mejor solución al problema, porque agrega un efecto de lentitud y espera del usuario, que es innecesario.

Aquí dejo la solución menos elegante:

…;
$('#modalBox).modal('show');

$.ajax({
  …,
  …,
}).done(function(response){
  setTimeOut(function(){
    $('#modalBox').modal('hide');
  }, 1000);
  …;
  …;
}).fail(function(){
  //
});

SOLUCIÓN RECOMENDADA

Debemos esperar a que el modal termine de mostrarse al usuario, momento en el que se disparará el evento “shown.bs.modal” y aquí es cuando debemos ejecutar el AJAX. De este modo no necesitaremos calcular los milisegundos necesarios para que termine la transición que muestra el modal (show).

$('#modalBox).on('shown.bs.modal', function(e){
  getData();
});

$('#modalBox).modal('show');

const getData = () => {
  …;
  $.ajax({
    …,
    …,
  }).done(function(response){
    $('#modalBox').modal('hide');
    //optional
    $('#modalBox).off('shown.bs.modal');
    …;
    …;
  }).fail(function(){
    //
  });
}

Este código ha sido probado con Bootstrap 5.2.x y 4.6.x.

Déjame saber si te ha resultado útil la explicación y la solución, escribiendo un comentario al final de este artículo.

¡Que tengas un gran día!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos requeridos están marcados *