Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass the value of an xhr onload function globally

In an app I'm creating I have the below XMLHttpRequest and I'm trying to pass the results of data inside the xhr.onload() into an array that's created within the same parent function.

var url = 'http://api.soundcloud.com/resolve.json?'+resource+'&'+CLIENT_ID;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function(){
    var data = JSON.parse(xhr.responseText);
    console.log(data.permalink_url);
};
xhr.send();

Below this I have the building blocks of an array and I'm trying to pass the results of data into the track string.

var metadata = {
        id: val,
        title: title,
        url: posturl,
        track: data.permalink_url
      };

Everything I've tried thus far either returns undefined or function and now I'm totally out of ideas...

like image 425
leaksterrr Avatar asked Nov 26 '13 02:11

leaksterrr


2 Answers

Ajax executes asynchronously (generally). This is vital to how Ajax works. What this means is that you can't count on the when the onload method will fire, or even if it will fire. What this means is that all code that depends on the xhr.responseText (result of the HTTP request) has to be done within the callback itself. For example:

xhr.onload = function () {
    // This will execute second
    doStuffWithData(JSON.parse(xhr.responseText));
}
// This will execute first
xhr.send();
var anything = anythingElse;
like image 68
Explosion Pills Avatar answered Sep 19 '22 21:09

Explosion Pills


Like I said in the comment to my previous answer, you can change the one line to xhr.open('GET', url, false). It will make the request synchronous and will prevent everything else from running until the request completes. It will allow you to access xhr.responseText without waiting for an onload function.

CLIENT_ID = 'client_id=xxx';
var src = track,
    match = src.match(/url=([^&]*)/),
    resource = match[0],
    stream = decodeURIComponent(match[1]) + '/stream/?' + '&' + CLIENT_ID;

var url = 'http://api.soundcloud.com/resolve.json?' + resource + '&' + CLIENT_ID;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send();

parsedResults.push({
    title: title,
    track: JSON.parse(xhr.responseText)
});

You can see it in action here. It appears to be broken in Chrome for some reason. Works in Firefox though. I assume it's something to do with the CORS + 302 redirect + synchronous request.

like image 31
idbehold Avatar answered Sep 20 '22 21:09

idbehold