0

I am confused why in the code below the first console.log shows me the object, yet the second is undefined. How do I fix this problem?

var listOfTweets = [];

for(var k = 0; k < search.length; k++){
    $.getJSON(searchURL, function(tweets){                              
        listOfTweets[k] = tweets;
        console.log(listOfTweets[k]);                               
    });
    console.log(listOfTweets[k]);
}
jordaninternets
  • 233
  • 2
  • 6
  • 15

4 Answers4

6

The getJSON is executed asyncronous and the last console.log is there for executed before the assignment

Since I don't know what you actually want is hard to tell you what you should do. What you need to keep in mind is the execution order.

In this code

 $.getJSON(searchURL, function(tweets){
          console.log("done");
    });
    console.log("Request send");

the first thing that happens is a request being send to searchURL then next thing is that "Request send" will be printed to the console and when the browser receives the response to the request then and no sooner will the function be called and "done" will be printed to the console

further your code has a problem with closure since k is closed over and will have the same value for all invocations of the call back (1)

to get around that problem you could use a self executing function

for(var k = 0;k<10;k++){
    $.getJSON(searchURL, (function(i){
          return function(tweets){  
                         console.log("done for " + i);
                 }
     }(k));
    console.log("Request send for " + k);
 }

notice that k is used as an argument for a function immediatedly, the value of the argument is stored for reference by the function return as the callback and will not change when k is incremented. If you do as you have done then since all callbacks are referencing the same object they will all also have the same value for k

(1) unless some returns before the looping ends

Rune FS
  • 21,497
  • 7
  • 62
  • 96
3

All of the $.getJSON calls are happening asynchronously. You're last "console.log" is likely being called "before" any of the getJSON calls are even done.

JMC
  • 910
  • 7
  • 11
1

Try saving k as follows:

var listOfTweets = [];

for(var k = 0; k < search.length; k++){
    $.getJSON(searchURL, function(tweets){    
        var kk = k; // saved!!                          
        listOfTweets[kk] = tweets;
        console.log(listOfTweets[kk]);                               
    });
    console.log(listOfTweets[k]);
}

Therefore when k is incremented it won't effect the kk that you saved

qwertymk
  • 34,200
  • 28
  • 121
  • 184
1

You will need a closure to save the current value of k to the callback's scope. Else, k is equal to search.length after the loop when the callbacks are executed. Also, see Javascript Callback Timing for when you will be able to use a filled listOfTweets.

var listOfTweets = [];
var search = [url1, url2, ...];

$.each(search, function(k, searchURL) {
    $.getJSON(searchURL, function(tweets){                              
        console.log(listOfTweets[k] = tweets);         
    });
});

// After all the ajax request completed, you will be able to
console.log(listOfTweets);
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375