0

I am attempting to make an array of objects in javascript but when i try and print the array to the console (using chrome) all i get is undefine, unless i print the array just after the push.

 var subitems = [];
 for (var i = 1; i < 1000; i = i + 50) {
       $.getJSON('http://gdata.youtube.com/feeds/api/users/' + username + '/subscriptions?max-results=50&start-index=' + i + '&alt=json', function (data) {
           var output = "";
           for (var x in data.feed.entry) {
               var subtitle = data.feed.entry[x].yt$username.$t;
               var subchannel = data.feed.entry[x].yt$channelId.$t;
               var subphoto = data.feed.entry[x].media$thumbnail.url;
               subitems.push({
                   subtitle: subtitle,
                   subchannel: subchannel,
                   subphoto: subphoto
               });
               console.log(subitems[0]); //Prints Fine
               output += '<div class="subtitle"><img src="' + subphoto + '"> <a href="http://www.youtube.com/channel/' + subchannel + '">' + propercase(subtitle) + '</a></div>';
           }
           maincontent.innerHTML = maincontent.innerHTML + output;
       });
 }
 console.log(subitems[0]); //This is undefined
Salman A
  • 262,204
  • 82
  • 430
  • 521
Mattigins
  • 1,014
  • 9
  • 25
  • Put console.log inside the getJSON function callback. Ajax as that is called is typically run asynchronously so the function can be called when ready, but the code immediately after the getJSON call gets run before that inner code is run. If it is done otherwise, it can lock up the page/interface. – Brett Zamir Aug 17 '13 at 09:47
  • Could it be possible that because xhr is asynchonous the subitems hasn't been set by the time you log it (when it's udefined)? – HMR Aug 17 '13 at 09:51
  • 1
    Additionally, I would avoid making *that* many Ajax calls at once. – Felix Kling Aug 17 '13 at 09:51
  • @HMR yes it is because XHR is asynchonous – Arun P Johny Aug 17 '13 at 09:51

2 Answers2

1

Here is the "easier" way of doing this: count XHR requests and fire the done function when all requests have returned:

var xhrCount = 0;
for (var i = 1; i < 1000; i = i + 50) {
    xhrCount++; // increment before request
    $.getJSON('http://gdata.youtube.com/feeds/api/users/' + username + '/subscriptions?max-results=50&start-index=' + i + '&alt=json', function (data) {
            // process response      
            // decrement after request is processed
            xhrCount--;
            if (xhrCount === 0) {
                // at this point all requests have returned  
                console.log(subitems);
            }
        }
    }
}

Update: a much better approach is to utilize jQuery.Deferred() object. A quick demo is setup here which needs some fixes. The general idea is to keep a track of all AJAX requests you make, pass them over to deferred.when() and assign the done function using the deferred.done(). Code (trimmed down for readability):

var subitems = [];
var deferreds = [];
for (var i = 1; i < 1000; i = i + 50) {
    var deferred = $.getJSON('https://gdata.youtube.com/feeds/api/users/warnerbrospictures/uploads?max-results=50&start-index=' + i + '&alt=json', function (data) {
        for (var j = 0; j < data.feed.entry.length; j++) {
            subitems.push({
                title: data.feed.entry[j].title.$t
            });
        }
    });
    deferreds.push(deferred);
}
$.when.apply($, deferreds).done(function () {
    console.clear();
    console.log(subitems);
    for (var i = 0; i < subitems.length; i++) {
        console.log(subitems[i].title);
    }
});

Note: Google data feeds contain the total number of results so it is possible to eliminate the hard coded "1000".

Salman A
  • 262,204
  • 82
  • 430
  • 521
-2

Try declaring your array as:

var subitems = [{}];
Himanshu Kumar
  • 541
  • 5
  • 14