0

Tengo este codigo:

<script type="text/javascript">
var direcciones = [];

function getDirecciones()
{
    $.ajax({
        url: "getDireccionesJSON.php",
        success: function (data)
        { 
            if (data != 0)
            {
                var datos = jQuery.parseJSON(data);

                for(var i = 0; i < datos.length; i++)
                {
                  var dato = { "sitio" : datos[i]["sitio"], "direccion" : datos[i]["direccion"] }   
                  direcciones.push(dato);
                }
            }
            else
                alert("No se pudo leer el json");
        }
    });

    for(var i = 0; i < direcciones.length; i++)
       document.write("Sitio: " + direcciones[i]["sitio"] + " Dirección: "  + direcciones[i]["direccion"] + "<br>");
}

getDirecciones();
</script>

Por que cuando llego al segundo ciclo for para recorrer el array direcciones me marca que no hay elementos, si se supone que en el primer ciclo for inserte en ese array los datos que venían en el json??

Jorge Alonso
  • 793
  • 1
  • 8
  • 24
  • JavaScript es asincrono , al realizar el for no hay nada el primero hace la funcion y luego en sengundo plano la llamada ajax, para hacer lo que quieres debes usar un callback o promesas – JackNavaRow Nov 09 '18 at 19:15
  • Te doy la bienvenida a Stackoverflow. ¿Qué muestra `console.log(datos);`? En estos casos conviene que pongas concretamente los datos sobre los que estás trabajando. – A. Cedano Nov 09 '18 at 19:16
  • Te recomiendo ir esta respuesta: https://es.stackoverflow.com/a/64403/7334 para comprender porque tiene ese comportamiento tu código. – Angel Oropeza Nov 09 '18 at 19:17
  • Mira mi respuesta en el enlace que te ha dado @AngelOropeza para una información más detallada. Para que entiendas esto de manera rápida, piensa en dos mundos paralelos. Uno ejecuta las líneas "normales" y el otro los _callbacks_ y _promesas_. En el mundo uno, se ejecuta todo el código que no sea un callback o una promesa en el orden en que están descritas, mientras que en el otro, en forma paralela, los callbacks y promesas. Cuando el mundo uno ejecuta el _for_, el mundo dos está "esperando" que el servidor devuelva los datos (en el _callback_). Es por esta razón que `direcciones` está vacío. – gugadev Nov 09 '18 at 19:23

3 Answers3

1

puedes hacerlo con funciones fetch():

fetch('getDireccionesJSON.php')
  .then(function(response) {
    // cuando termine la peticion retornara los datos
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
    // ya aqui a terminado y tienes los datos disponibles y puedes trabajarlo como gustes
  })
.catch(function(error) {
// si ocurre un error en la peticion!
  console.log('Hubo un problema con la petición Fetch:' + error.message);
});;

o mejorando tu ejemplo:

var direcciones = [];
var content="";
function getDirecciones()
{
   var res= $.ajax({
        url: "getDireccionesJSON.php",
       dataType: "json",
    });


    return res;

}

getDirecciones().done(function(response){
            if (data != 0)
            {
                var datos = jQuery.parseJSON(data);

                for(var i = 0; i < datos.length; i++)
                {
                 content += `Sitio: ${direcciones[i]["sitio"]} Dirección: ${direcciones[i]["direccion"]} <br>`;
                }
            }
            else
                alert("No se pudo leer el json");
        }
       document.write(content);

});
Bryro
  • 8,278
  • 1
  • 7
  • 24
0

Mira mi respuesta en el enlace que te ha dado @AngelOropeza en los comentarios para una información más detallada. Para que entiendas esto de manera rápida, piensa en dos mundos paralelos:

  • Uno ejecuta las líneas "normales"
  • El otro ejecuta los callbacks y promesas (procesos asíncronos).

En el mundo uno, se ejecuta todo el código que no sea un callback o una promesa en el orden en que están descritas, mientras que en mundo dos, en forma paralela, los callbacks y promesas. Cuando el mundo uno ejecuta el for, el mundo dos está "esperando" que el servidor devuelva los datos (en el callback); es decir, la función que le pasas a success aún no se resuelve. Es por esta razón que direcciones está vacío.

¿Cuál es la solución?

Así como está, puedes pasarle un callback a getDirecciones de modo que se ejecute una vez las direcciones estén listas:

function getDirecciones(cb)
{
    $.ajax({
        url: "getDireccionesJSON.php",
        success: function (data)
        {
            if (data != 0)
            {
                const direcciones = []
                const datos = jQuery.parseJSON(data);

                for(var i = 0; i < datos.length; i++)
                {
                  const dato = { "sitio" : datos[i]["sitio"], "direccion" : datos[i]["direccion"] }   
                  direcciones.push(dato);
                }
                cb(direcciones)
            }
            else
                alert("No se pudo leer el json");
        }
    });
}

Nota: se puede simplicar el código de la siguiente manera:

const direcciones = datos.map(({ sitio, direccion }) => ({ sitio, direccion })
cb(direcciones)

Y por último, llamas a la función de esta manera:

getDirecciones((direcciones) => {
    for(var i = 0; i < direcciones.length; i++) {
           document.write("Sitio: " + direcciones[i]["sitio"] + " Dirección: "  + 
           direcciones[i]["direccion"] + "<br>");
    }
});
gugadev
  • 18,776
  • 1
  • 24
  • 49
0

Sucede que cuando haces una petición ajax realmente estás imaginariamente abriendo una pestaña nueva en el navegador y accediendo a una URL, el tiempo que tarda en responder el servidor se refleja como en la vida real, pero javascript no espera a que termine este proceso y continua mientras que tu variable sigue intácta hasta que el servidor responda y se complete la petición.

Para que tu código funcione solo debes meter la iteración dentro de success(Que es la función que se llama una vez el servidor responde),

<script type="text/javascript">
var direcciones = [];

function getDirecciones()
{
    $.ajax({
        url: "getDireccionesJSON.php",
        success: function (data)
        { 
            if (data != 0)
            {
                var datos = jQuery.parseJSON(data);

                for(var i = 0; i < datos.length; i++)
                {
                  var dato = { "sitio" : datos[i]["sitio"], "direccion" : datos[i]["direccion"] }   
                  direcciones.push(dato);
                }
    for(var i = 0; i < direcciones.length; i++)
       document.write("Sitio: " + direcciones[i]["sitio"] + " Dirección: "  + direcciones[i]["direccion"] + "<br>");

            }
            else
                alert("No se pudo leer el json");
        }
    });

}

getDirecciones();
</script>

Te dejo un enlace hacía la documentación de jQuery y de el método ajax. http://api.jquery.com/jquery.ajax/

Jorhel Reyes
  • 173
  • 8