2

I'm trying to get the return value of a utility method I wrote using jquery:

function loadFrames(coords, spritesheet) {
    return $.ajax({
        type: "GET",
        url: coords,
        dataType: "xml",
        success: function(xml,code,obj) {return parseFrameData(xml, spritesheet);}
    });
}

So, this method receives two arguments, opens a file (the one pointed to by the "plist" argument) and runs the parseFrameData method. The latter returns an array of objects.

I would like to use this the following way:

var frames = loadFrames('player.xml', 'spritesheet.png');

but I don't find the way to say "return the value of the method you called on line starting with "'success:' "...

Petah
  • 45,477
  • 28
  • 157
  • 213
Jem
  • 6,226
  • 14
  • 56
  • 74
  • I don't see the "plist" argument, what did you mean by that? – Slider345 Oct 13 '11 at 12:07
  • That's because you have forgotten that you're using an _asynchronous_ call. The callback executes in a different context of execution than does `loadFrames`, which will pretty much always return long before the callback even fires. You also didn't bother searching or looking in the list of "Related" topics, as this has been asked _millions of times before_. – Lightness Races in Orbit Oct 13 '11 at 12:09
  • Entirely, completely a duplicate of [jQuery: Return data after ajax call success](http://stackoverflow.com/questions/5316697/jquery-return-data-after-ajax-call-success) – Lightness Races in Orbit Oct 13 '11 at 12:09

2 Answers2

2

Edit: An answer posted to the question @Tomalak linked to informed me of this cool concept of 'Promises', which you might also want to take a look at.

The point of using $.ajax is generally to make asynchronous requests. Calling it and expecting a value to be returned immediately would be a synchronous request.

That being said, you can do what you're asking by using $.ajax in synchronous mode by setting async:false. This may have the affect of locking your browser until the request completes.

function loadFrames(coords, spritesheet) {
  var myFrames;

  $.ajax({
    type: "GET",
    url: coords,
    dataType: "xml",
    async: false,
    success: function(xml,code,obj) {myFrames = parseFrameData(xml, spritesheet);}
  });
  return myFrames;
}

var frames = loadFrames('player.xml', 'spritesheet.png');

I believe that is will work, but I don't have a good way to test it. Can anyone else confirm this approach?

Still it would be much better to do this asynchronously the way @Petah suggests.

Community
  • 1
  • 1
Slider345
  • 4,558
  • 7
  • 39
  • 47
  • Yes indeed, very useful when the loaded resources need to be available right after finishing the execution of the utility method. Thanks for the help! It's a great solution to my blocker! – Jem Oct 13 '11 at 18:49
  • *"You will also need to use a global variable to accomplish this..."* Absolutely not, just use a local variable within the `loadFrames` function. But even better is to [use a callback as demonstrated in this other answer](http://stackoverflow.com/questions/7871903/returning-json-data-out-of-the-callback-function/7871925#7871925), synchronous requests make for a poor user experience. – T.J. Crowder Oct 24 '11 at 06:45
  • @T.J.Crowder - good point! I have revised my answer to demonstrate this. Also I had two 'return's in there which was wrong. – Slider345 Oct 24 '11 at 18:56
1

Ajax runs asynchronously (meaning in the background, allowing other things to continue) so you wont be able to directly return a value from it.

How ever, you can pass the function a callback that will be called once the Ajax request is finished.

function loadFrames(coords, spritesheet, callback) {
    $.ajax({
        type: "GET",
        url: coords,
        dataType: "xml",
        success: function(xml,code,obj) { callback(parseFrameData(xml, spritesheet)); }
    });
}

Also, on a side note, dont forget to check for HTTP errors like 404 and 500 by passing a error paramter to the ajax call

Petah
  • 45,477
  • 28
  • 157
  • 213