4

How do I return the result of the nested ajax call as the result of the parent function?

//Declaring the function
var myFunction = function(myData){  
  $.ajax({
  type:'post',
  url:"/ajaxPage.php",
  data:{data:myData},
  success:function(r){
  return r;
  });
}

//Calling the function
var theResult = myFunction(myData);

I want the variable 'theResult' to hold the contents of the ajax call.

wilsonpage
  • 17,341
  • 23
  • 103
  • 147

4 Answers4

7

Since the ajax is asynchronous you cannot return it in the parent function. What you can do, is to provide a callback function, and you call it as well with the result.

 //Declaring the function

var myFunction = function(myData, callback){  
  $.ajax({
  type:'post',
  url:"/ajaxPage.php",
  data:{data:myData},
  success:function(r){
    callback(r);
  });
}


//Calling the function
var theResult = myFunction(myData, function(res) {
    // deal with it..
});
José Leal
  • 7,989
  • 9
  • 35
  • 54
  • As the title implies - we want to return it, not to "deal with it". Like here: http://stackoverflow.com/questions/35508182/js-return-from-nested-function-after-ajax-call – pesho hristov Feb 19 '16 at 14:54
3

If you're using jQuery, you should definitely be using $.Deferred() and Promises/A. I've made this more verbose that you really need to demonstrate some of the functionality. $.ajax itself is already returning a $.Deferred().promise() so you can actually just cut out the extra step if you only need to make the one XHR request (see bottom example).

//Declaring the function
var myFunction = function(myData){
  var deferredResponse = new $.Deferred();
  $.ajax({
    type:  'post',
    url:   '/ajaxPage.php',
    data: {'data': myData}
  }).done(deferredResponse.resolve).fail(deferredResponse.reject);
  return deferredResponse.promise();
}

//Calling the function
$.when(myFunction(myData)).done(function(response){
  var theResult = response;
});

The verbose syntax comes in handy when you have multiple nested XHR requests and want to return the response of the inner-most call: deferredResponse.resolve(innerResponse). Here's the simply version.

//Declaring the function
var myFunction = function(myData){
  return $.ajax({
    type:  'post',
    url:   '/ajaxPage.php',
    data: {'data': myData}
  });
}

//Calling the function
myFunction(myData).done(function(response){
  var theResult = response;
});
idbehold
  • 16,833
  • 5
  • 47
  • 74
2

You will have to make your AJAX call synchronous (not asynchronous which is the default).

Something like this:

//Declaring the function
var myFunction = function(myData){
  var returnValue = null;
  $.ajax({
  type:'post',
  async: false,
  url:"/ajaxPage.php",
  data:{data:myData},
  success:function(r){
  returnValue = r;
  });

  return returnValue;
}

//Calling the function
var theResult = myFunction(myData);
Jan Hančič
  • 53,269
  • 16
  • 95
  • 99
  • He didn't say that it has to be :) – Jan Hančič Mar 23 '11 at 10:01
  • Brilliant! Thank you Hancicicicici! Very interesting I didn't know you could remove the async nature of this function. Are there any other jquery functions that this can be applied to? – wilsonpage Mar 23 '11 at 10:09
  • 2
    Making AJAX synchronous is backwards. The appropriate approach is to turn the code that handles the response into a continuation passed to myFunction`, as José's answer shows. – outis Jan 14 '12 at 06:42
1

Try this:

var myFunction = function(myData){  
  $.ajax({
  type:'post',
  url:"/ajaxPage.php",
  data:{data:myData},
  success:function(r){
       return arguments.callee(r);
  });
}

//Calling the function
var theResult = myFunction(myData);
Prakash
  • 6,562
  • 3
  • 25
  • 33