Txarli
Txarli

Reputation: 78

Javascript global variable remains 'undefined' after changing it in a function

I was trying to do a JS script that takes the last videos from a YouTube channel. I wanted to take, from each video, the title, id and thumbnail, to use them in my page. My first option was creating a global array with all the videos, to use it in other functions (createThumbnail, createPlayer...). This is the code where I take the channel's latest videos:

user = 'PiewDiePie'

var videos = [];

$.getJSON('http://gdata.youtube.com/feeds/users/' + user + '/uploads?alt=json-in-script&format=5&callback=?', null, function(data) {
    var feed = data.feed;
    $.each(feed.entry, function(i, entry) {
        var video = {
            title: entry.title.$t,
            id: entry.id.$t.match('[^/]*$'),
            thumbnails: entry.media$group.media$thumbnail
        };
        videos.push(video);
    });
    alert('Inside function: ' + videos[0].title);
});

alert('Outside function: ' + videos[0].title);

// Functions with the videos array

The problem here is that the first alert shows the title but, the second one, gives the following error:

Uncaught TypeError: Cannot read property 'title' of undefined

Finally, I've changed my script avoiding the use global scope variables but I can't understand why this wasn't working. I'm new to javascript, probably this is something evident for an expert...

Thank you very much

Upvotes: 0

Views: 713

Answers (1)

Mitya
Mitya

Reputation: 34628

Your problem is one of chronology.

Your request to the YouTube API is asynchronous, meaning while it's happening the rest of your code after it will continue to be executed. So when your second alert fires, the request hasn't completed yet, and so the videos array is not yet populated.

Instead, your second alert needs to wait for the request to resolve.

Change

$.getJSON(...

to

var req = $.getJSON(....

Then wrap your second alert in a callback for the request

req.done(function() { alert('Outside function: ' + videos[0].title); });

Upvotes: 1

Related Questions