2

I'm trying to read in several urls as text and store them into an array with jquery's ajax/get. I need to wait for all data to be obtained (and pushed to an array) and then return it in a function. From what I read online, this isn't possible.

I figured if I set a global array variable and pushed into that every time new data is obtained, then checked using a while loop if the array is saturated, when it is return. See below

You can assume all errors are handled within the get call

function fetchData(){
   x = [1,2,3,4,5,6,7,8,9,10];
   a = [];

   //Loop, get and push data
   $.each(x, function( i, val ) {
       $.get("http://someurl/"+i, function( data ) {
           a.push(data);
       });
   });

   // Wait till our array is populated?
   while(a.length < x.length){
       console.log(a.length);
   }
   return a;
}

However, this approach does not seem to be working and nothing is ever added to the array.. Can someone point me in the right direction?

Thank you

Omar Wagih
  • 8,504
  • 7
  • 59
  • 75
  • trying to return a value from a async function is a very bad idea... instead why don't make use a callback mechanism – Arun P Johny Nov 21 '13 at 04:09
  • possible duplicate of [Return value from callback function](http://stackoverflow.com/questions/4897748/return-value-from-callback-function) – Dagg Nabbit Nov 21 '13 at 04:12
  • possible duplicate of [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) and [Javascript callback for multiple ajax calls](http://stackoverflow.com/questions/4368946/javascript-callback-for-multiple-ajax-calls) – Felix Kling Nov 21 '13 at 08:34

3 Answers3

3

The solution you are looking for is to use a callback

function fetchData(callback) {
    var requests = [];
    for (var i = 1; i <= 10; i++) {
        requests.push($.get("http://someurl/" + i))
    }

    $.when.apply($, requests).then(function () {
        var array = $.map(arguments, function (arg) {
            return arg[0];
        });
        callback(array);
    })
}

fetchData(function (array) {
    //do something with array
})

PoC: Fiddle

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Could you explain what you're doing with the second half part where you call `args[0]` I'm not getting the expected results. – Omar Wagih Nov 21 '13 at 05:00
  • the `then` callback will get an array of parameters which are the arguments of each of the target ajax calls... so each of those has 3 items the data, status and ajax request from which we need to fetch only the data which is `data[0]` – Arun P Johny Nov 21 '13 at 05:07
2

issue 1

Here you are doing console.log on the result array even before the callbacks get fired. So the array a will always be empty. What you want to do is to trigger the console.log after all the values in array x are processed.

issue 2

You are trying to return the result array back. Instead you should try getting the code that processes a inside the callback.

like

function fetchData(cb){
   x = [1,2,3,4,5,6,7,8,9,10];
   a = [];

   //Loop, get and push data
   $.each(x, function( i, val ) {
       $.get("http://someurl/"+i, function( data ) {
           a.push(data);
           
           if(a.length == x.length) {
                //looping logic taken inside callback
                while(a.length < x.length){
                   console.log(a.length);
                   
               }
               //calling the callback on result
               cb(a);
           }
           
       });
   });  
   
}

fetchData(function(data){

    //process a here

});
Community
  • 1
  • 1
Mithun Satheesh
  • 27,240
  • 14
  • 77
  • 101
1

In this way you can't make sure ajax calls will be done synchronously. To do so you can do a normal ajax call or you can use ajaxSetup.

In those ways you can make sure array will be read after all calls been processed. You better to have a timeout too, because some call may not return in time.

Maleen Abewardana
  • 13,600
  • 4
  • 36
  • 39