leaksterrr
leaksterrr

Reputation: 4167

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...

Upvotes: 11

Views: 12245

Answers (3)

leaksterrr
leaksterrr

Reputation: 4167

I've gone for Explosion Pills solution. The only problem I encounter is that the links that get crawled don't always come back in the same order each time I run the node app. Realistically they should return in the order that they're crawled in (which would be newest posts first, right?) However this isn't always the case?

Upvotes: 0

idbehold
idbehold

Reputation: 17168

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.

Upvotes: 1

Explosion Pills
Explosion Pills

Reputation: 191749

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;

Upvotes: 6

Related Questions