javascript promises, ajax() requests

Question:

Greetings,

I have been struggling for a long time with a problem that I cannot solve, I hope you can help me, I have reviewed many tutorials on callbacks and promises but I cannot solve my problem.

Basically I need to make a $.ajax() request which brings me data, later in an iterative cycle for each data I make another $.ajax() query to another table, finally I need to use the data from both queries to fill two arrays and send them as arguments to a function.

With the first request I have no problems and in the second the console shows me that I got the data but I can't show it.

I leave you the code that I am doing (I am working with jquery):

// Funcion para traer datos adicionales por cada registro
function funcionAsync(urlDestino){
  // La función devuelve una Promise
    return new Promise(function(resolver, rechazar){
        jQuery.ajax({
          url: urlDestino,
          success : function(data){resolver(data)},
          error : function(error){rechazar(error)}
        });    
    });
}

// Funcion principal para solicitar datos con Ajax
function TraeDatosConAjax(){

var datos1 = [], datos2 = [];
var urlPrincipal = $("#urlPrincipal").val(); // URL Base

$.getJSON(urlPrincipal+'MetodoTraeDatos1') // Primera peticion Ajax
  .then(function(respuesta) {
    labelx = "";

    for (var i = 0; i < respuesta.length; i++) {
        ini = respuesta[i].ini_semana; // fecha inicial
        fin = respuesta[i].fin_semana; // fecha final
        var datos = "";

        labelx = abreviaRangoFechas(ini, fin); // Funcion que abrevia el rango de fechas
        // Llenamos el primer array (datos1) con datos (SE LLENA SIN PROBLEMAS)
        datos1.push({
            y: parseInt(respuesta[i].cant_capacidad), label: labelx, s: respuesta[i].id_semana,
        });

        // Llenaremos datos2 con la funcion asincrona
        datos = funcionAsync(urlPrincipal+'MetodoTraeDatos2/'+respuesta[i].id_semana+'/')
        .then(function(datosDevueltos){
            if ($.isNumeric(datosDevueltos[0].cantprog_progweek)) {valor = datosDevueltos[0].cantprog_progweek;}else{valor = 0;}
            // lleno el segundo array con datos de la segunda peticion (ACA TENGO EL PROBLEMA PARA LLENAR EL ARRAY)
            /********************************************************/
            datos2.push({
                y: parseInt(valor), label: labelx,
            });
            /********************************************************/
            return valor;
        }, function(errorLanzado){
          // Aquí el código para hacer algo cuando ocurra un error.
          alert("Fallo!!!");
        });
        //alert("Fuera: "+datos); //return datos1; // LO EXTRAÑO ES QUE SI LE QUITO EL COMENTARIO A ESTE ALERT() OBTENGO LOS DATOS QUE NECESITO
    }
    // Aca necesito asignar ambos array (datos1 y datos2) como argumento de "GraphAreaGeneric" * DATOS1 SE CARGA SIN PROBLEMAS, DATOS2 SE CARGA SOLO SI DESCOMENTO EL ALERT()*
    GraphAreaGeneric(datos1, datos2);
    //return datos1;
  })
}

Answer:

The problem is that the AJAX requests are asynchronous, when you are doing GraphAreaGeneric(datos1, datos2); outside the function it is very likely that data1 and data2 have not been loaded yet.

You have two solutions to the problem:

  1. Put the statement GraphAreaGeneric(datos1, datos2); inside the .then() being like this:

     $.getJSON(urlPrincipal+'MetodoTraeDatos1') // Primera peticion Ajax .then(function(respuesta) { labelx = ""; for (var i = 0; i < respuesta.length; i++) { ini = respuesta[i].ini_semana; // fecha inicial fin = respuesta[i].fin_semana; // fecha final var datos = ""; labelx = abreviaRangoFechas(ini, fin); datos1.push({ y: parseInt(respuesta[i].cant_capacidad), label: labelx, s: respuesta[i].id_semana, }); // Llenaremos datos2 con la funcion asincrona funcionAsync(urlPrincipal+'MetodoTraeDatos2/'+respuesta[i].id_semana+'/') .then(function(datosDevueltos){ if ($.isNumeric(datosDevueltos[0].cantprog_progweek)) {valor = datosDevueltos[0].cantprog_progweek;}else{valor = 0;} // lleno el segundo array con datos de la segunda peticion (ACA TENGO EL PROBLEMA PARA LLENAR EL ARRAY) /********************************************************/ datos2.push({ y: parseInt(valor), label: labelx, }); /********************************************************/ GraphAreaGeneric(datos1, datos2); datos = valor; }, function(errorLanzado){ // Aquí el código para hacer algo cuando ocurra un error. alert("Fallo!!!"); }); }
  2. Making an AJAX request using the $.ajax() function with asynchronous mode disabled is explained very well here . As in the comment below very well said by the user rnd this option is not recommended as it affects the final user experience.

I hope I've helped.

Tell us how it went please!

Scroll to Top