0

En la siguiente función necesito devolver dos tablas en forma de string.

Cuestión necesito que la siguiente función se ejecute en el orden en el que está escrito (de hecho van a ver que puse unos alerts para comprobar el orden de ejecución (todos funcionan bien, la información esta bien, es enviada y recibida de forma correcta) y que no haya errores en el manejo de las variables. Si logro que así sea estoy bastante seguro de que funcionará.

Lo que hago es crear un array para guardar los valores de lo que sería tabla1 ... tablaN para luego transformarlos en un string que sea tabla1;..tablaN;

Les dejo este código de referencia por que es el framework que estoy utilizando:

https://datatables.net/examples/api/row_details.html

Necesito devolver esto como string por el siguiente código:

Más puntualmente por la función ( format(row.data()) en la siguiente parte del código (al final).

 else {
     // Open this row
     row.child( format(row.data()) ).show();
     tr.addClass('shown');
 }

Mi código, el que debería devolver las dos tablas como strings, es el siguiente:

function format ( d ) {

  var expand = [];

  alert('Paso 1: El ID seleccionado es: ' + d.id_pedido);
       $.ajax({  
       type: 'POST',  
       url: '../../php/compras-table.php', 
       data: { 'id_pedido': d.id_pedido },
       success: function(data) {

  alert('Paso 2: La data es devuelta del archivo PHP: (Ver consola) ');
       console.log(data);
       var resp = JSON.parse(data);

  alert('Paso 3: La data es convertida a Ajax: '+resp.expand[0].descripcion+' '+resp.expand[0].cantidad+' '+resp.expand[0].unidad);

  for (var a = 0; a < Object.keys(resp.expand).length; a++){
      // `d` is the original data object for the row
      expand[a] = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
          '<tr>'+
               '<td>Full name:</td>'+
               '<td>'+resp.expand[a].descripcion+'</td>'+
          '</tr>'+
          '<tr>'+
               '<td>Extension number:</td>'+
               '<td>'+resp.expand[a].cantidad+'</td>'+
          '</tr>'+
          '<tr>'+
                '<td>Extra info:</td>'+
                '<td>Turpis egestas maecenas pharetra convallis posuere morbi leo. 
                     Gravida arcu ac tortor dignissim. Lectus sit amet est placerat in egestas erat. 
                     Morbi tristique senectus et netus et malesuada fames.
                     Imperdiet massa tincidunt nunc pulvinar sapien et ligula. 
                     Purus in mollis nunc sed. Nulla facilisi cras fermentum odio eu feugiat pretium. 
                     Sit amet nulla facilisi morbi tempus iaculis urna id. Interdum posuere lorem ipsum dolor sit amet consectetur. 
                     Viverra adipiscing at in tellus integer feugiat scelerisque varius. 
                     Amet justo donec enim diam. Posuere sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper.
                </td>'+
           '</tr>'+
        '</table>';
        //alert(expand);
   } 
   alert('Convirtiendo' + expand.join());
   expand = expand.join(';');
   expand = expand +';';
   alert('Convertido' + expand);
   return expand;
 }
})

/*expand = expand.join(';');
expand = expand +';';*/
alert('Prueba final' + expand);
return expand;

}

Lo que sucede es que se ejecuta primero el primer paso y luego la parte que dice "Prueba final" sin recibir la información de ajax previamente.

Shaz
  • 28,742
  • 18
  • 37
  • 61
  • Debes de tener un error en el ajax que no ejecuta bien y salta esa parte. Te dejo el enlace a una respuesta que di donde explico cómo debuguear si todo va bien: https://es.stackoverflow.com/questions/241053/por-que-no-funciona-esta-petici%C3%B3n-de-jquery-ajax/241057#241057 – Iñigo Irigoyen Erquicia Mar 05 '19 at 07:22
  • 1
    Posible duplicado de [¿Cómo obtener la respuesta de una llamada asíncrona (AJAX) fuera de ella?](https://es.stackoverflow.com/questions/1539/c%c3%b3mo-obtener-la-respuesta-de-una-llamada-as%c3%adncrona-ajax-fuera-de-ella) – Pablo Lozano Mar 05 '19 at 08:14
  • Las llamadas AJAX son asíncronas, con lo que es normal que te pase eso. Tienes que aprender a gestionar esta asincronía (te recomiendo que aprendas sobre Promesas) para conseguir obtener lo que quieres. – Pablo Lozano Mar 05 '19 at 08:16

1 Answers1

0

El problema es la sincronía en tu función. Como has podido comprobar, los pasos 2 y 3 se ejecutan después del paso final, esto es por que los pasos 2 y 3 están en una función asíncrona, que se ejecutará cuando se resuelva tu petición. La ejecución del código cuando trabajas con promesas y peticiones deja de ser 100% secuencial, es decir, no se ejecuta linea a linea.

En tu caso, la solución sería trabajar con callbacks, que son funciones que se ejecutan cuando una acción termina o en tu caso, cuando el servidor responde a una petición:

function format ( d, callback ) {

var expand = [];

alert('Paso 1: El ID seleccionado es: ' + d.id_pedido);
            $.ajax({  
            type: 'POST',  
            url: '../../php/compras-table.php', 
            data: { 'id_pedido': d.id_pedido },
            success: function(data) {

                alert('Paso 2: La data es devuelta del archivo PHP: (Ver consola) ');
                console.log(data);
                var resp = JSON.parse(data);
                alert('Paso 3: La data es convertida a Ajax: '+resp.expand[0].descripcion+' '+resp.expand[0].cantidad+' '+resp.expand[0].unidad);

                            for (var a = 0; a < Object.keys(resp.expand).length; a++){
                                // `d` is the original data object for the row
                               expand[a] = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
                                    '<tr>'+
                                        '<td>Full name:</td>'+
                                        '<td>'+resp.expand[a].descripcion+'</td>'+
                                    '</tr>'+
                                    '<tr>'+
                                        '<td>Extension number:</td>'+
                                        '<td>'+resp.expand[a].cantidad+'</td>'+
                                    '</tr>'+
                                    '<tr>'+
                                        '<td>Extra info:</td>'+
                                        '<td>Turpis egestas maecenas pharetra convallis posuere morbi leo. Gravida arcu ac tortor dignissim. Lectus sit amet est placerat in egestas erat. Morbi tristique senectus et netus et malesuada fames. Imperdiet massa tincidunt nunc pulvinar sapien et ligula. Purus in mollis nunc sed. Nulla facilisi cras fermentum odio eu feugiat pretium. Sit amet nulla facilisi morbi tempus iaculis urna id. Interdum posuere lorem ipsum dolor sit amet consectetur. Viverra adipiscing at in tellus integer feugiat scelerisque varius. Amet justo donec enim diam. Posuere sollicitudin aliquam ultrices sagittis orci a scelerisque purus semper.</td>'+
                                    '</tr>'+
                                '</table>';
                                //alert(expand);
                            } 
                            alert('Convirtiendo' + expand.join());
                            expand = expand.join(';');
                            expand = expand +';';
                            alert('Convertido' + expand);
                            callback(expand);
                            return expand;
                    }
            })
}

Entonces, la llamada a tu función pasaría a ser la siguente:

        else {
            format(row.data(), function(expand) {
               row.child(expand).show();
               tr.addClass('shown');
            }).bind(this);
        }

Como ves, hemos añadido al final de tu función format la llamada al callback que hemos pasado como parámetro a la función. Ese callback se ejecutará, esta vez si, cuando la petición al servidor finalice, y de este modo tendrás los datos que quieres a la hora de pintar tu row

Shaz
  • 28,742
  • 18
  • 37
  • 61
Ilsanchez
  • 630
  • 3
  • 10