544

I have something like this, where it is a simple call to a script that gives me back a value, a string..

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {
         return data; 
      }
   });
}

but if I call something like this

var output = testAjax(svar);  // output will be undefined...

so how can I return the value? the below code does not seem to work either...

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {

      }
   });
   return data; 
}
1

5 Answers 5

455

Note: This answer was written in February 2010.
See updates from 2015, 2016 and 2017 at the bottom.

You can't return anything from a function that is asynchronous. What you can return is a promise. I explained how promises work in jQuery in my answers to those questions:

If you could explain why do you want to return the data and what do you want to do with it later, then I might be able to give you a more specific answer how to do it.

Generally, instead of:

function testAjax() {
  $.ajax({
    url: "getvalue.php",  
    success: function(data) {
      return data; 
    }
  });
}

you can write your testAjax function like this:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

Then you can get your promise like this:

var promise = testAjax();

You can store your promise, you can pass it around, you can use it as an argument in function calls and you can return it from functions, but when you finally want to use your data that is returned by the AJAX call, you have to do it like this:

promise.success(function (data) {
  alert(data);
});

(See updates below for simplified syntax.)

If your data is available at this point then this function will be invoked immediately. If it isn't then it will be invoked as soon as the data is available.

The whole point of doing all of this is that your data is not available immediately after the call to $.ajax because it is asynchronous. Promises is a nice abstraction for functions to say: I can't return you the data because I don't have it yet and I don't want to block and make you wait so here's a promise instead and you'll be able to use it later, or to just give it to someone else and be done with it.

See this DEMO.

UPDATE (2015)

Currently (as of March, 2015) jQuery Promises are not compatible with the Promises/A+ specification which means that they may not cooperate very well with other Promises/A+ conformant implementations.

However jQuery Promises in the upcoming version 3.x will be compatible with the Promises/A+ specification (thanks to Benjamin Gruenbaum for pointing it out). Currently (as of May, 2015) the stable versions of jQuery are 1.x and 2.x.

What I explained above (in March, 2011) is a way to use jQuery Deferred Objects to do something asynchronously that in synchronous code would be achieved by returning a value.

But a synchronous function call can do two things - it can either return a value (if it can) or throw an exception (if it can't return a value). Promises/A+ addresses both of those use cases in a way that is pretty much as powerful as exception handling in synchronous code. The jQuery version handles the equivalent of returning a value just fine but the equivalent of complex exception handling is somewhat problematic.

In particular, the whole point of exception handling in synchronous code is not just giving up with a nice message, but trying to fix the problem and continue the execution, or possibly rethrowing the same or a different exception for some other parts of the program to handle. In synchronous code you have a call stack. In asynchronous call you don't and advanced exception handling inside of your promises as required by the Promises/A+ specification can really help you write code that will handle errors and exceptions in a meaningful way even for complex use cases.

For differences between jQuery and other implementations, and how to convert jQuery promises to Promises/A+ compliant, see Coming from jQuery by Kris Kowal et al. on the Q library wiki and Promises arrive in JavaScript by Jake Archibald on HTML5 Rocks.

How to return a real promise

The function from my example above:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

returns a jqXHR object, which is a jQuery Deferred Object.

To make it return a real promise, you can change it to - using the method from the Q wiki:

function testAjax() {
  return Q($.ajax({
      url: "getvalue.php"
  }));
}

or, using the method from the HTML5 Rocks article:

function testAjax() {
  return Promise.resolve($.ajax({
      url: "getvalue.php"
  }));
}

This Promise.resolve($.ajax(...)) is also what is explained in the promise module documentation and it should work with ES6 Promise.resolve().

To use the ES6 Promises today you can use es6-promise module's polyfill() by Jake Archibald.

To see where you can use the ES6 Promises without the polyfill, see: Can I use: Promises.

For more info see:

Future of jQuery

Future versions of jQuery (starting from 3.x - current stable versions as of May 2015 are 1.x and 2.x) will be compatible with the Promises/A+ specification (thanks to Benjamin Gruenbaum for pointing it out in the comments). "Two changes that we've already decided upon are Promise/A+ compatibility for our Deferred implementation [...]" (jQuery 3.0 and the future of Web development). For more info see: jQuery 3.0: The Next Generations by Dave Methvin and jQuery 3.0: More interoperability, less Internet Explorer by Paul Krill.

Interesting talks

UPDATE (2016)

There is a new syntax in ECMA-262, 6th Edition, Section 14.2 called arrow functions that may be used to further simplify the examples above.

Using the jQuery API, instead of:

promise.success(function (data) {
  alert(data);
});

you can write:

promise.success(data => alert(data));

or using the Promises/A+ API:

promise.then(data => alert(data));

Remember to always use rejection handlers either with:

promise.then(data => alert(data), error => alert(error));

or with:

promise.then(data => alert(data)).catch(error => alert(error));

See this answer to see why you should always use rejection handlers with promises:

Of course in this example you could use just promise.then(alert) because you're just calling alert with the same arguments as your callback, but the arrow syntax is more general and lets you write things like:

promise.then(data => alert("x is " + data.x));

Not every browser supports this syntax yet, but there are certain cases when you're sure what browser your code will run on - e.g. when writing a Chrome extension, a Firefox Add-on, or a desktop application using Electron, NW.js or AppJS (see this answer for details).

For the support of arrow functions, see:

UPDATE (2017)

There is an even newer syntax right now called async functions with a new await keyword that instead of this code:

functionReturningPromise()
    .then(data => console.log('Data:', data))
    .catch(error => console.log('Error:', error));

lets you write:

try {
    let data = await functionReturningPromise();
    console.log('Data:', data);
} catch (error) {
    console.log('Error:', error);
}

You can only use it inside of a function created with the async keyword. For more info, see:

For support in browsers, see:

For support in Node, see:

In places where you don't have native support for async and await you can use Babel:

or with a slightly different syntax a generator based approach like in co or Bluebird coroutines:

More info

Some other questions about promises for more details:

9
  • They are just messing around with ajax, seeing how it works.
    – Techism
    Commented Mar 15, 2011 at 19:21
  • 6
    Perfect answer!Just to add a side note for users, this will not work with jQuery ver 1.4.
    – uadnal
    Commented Apr 1, 2011 at 14:41
  • 9
    This helped a lot. I just skipped on step var promise = testAjax() and did this testAjax().success(function (data) { alert(data); }); Commented Jul 11, 2012 at 19:55
  • @rsp great answer indeed! But I've followed your demo code, and it seems to call ajax twice (does anyone else noticed the same?).
    – thicolares
    Commented Feb 19, 2013 at 12:33
  • 1
    @AlexG In place of promise.success(function (data) { alert(data); }); in my example you can use promise.success(function (data) { alert(data.users[0].id); alert(data.prices[x]); }); or something like that. If you get the data in the success callback (or then callback, if you're using the Promises/A+ API) then you get the data with all of its properties.
    – rsp
    Commented Jun 27, 2016 at 6:27
427

The only way to return the data from the function would be to make a synchronous call instead of an asynchronous call, but that would freeze up the browser while it's waiting for the response.

You can pass in a callback function that handles the result:

function testAjax(handleData) {
  $.ajax({
    url:"getvalue.php",  
    success:function(data) {
      handleData(data); 
    }
  });
}

Call it like this:

testAjax(function(output){
  // here you use the output
});
// Note: the call won't wait for the result,
// so it will continue with the code here while waiting.
9
  • I guess adding [success] status would delay some and more accurate to only call when status is 400 successful.
    – meYnot
    Commented Jan 6, 2016 at 17:03
  • 1
    @iamsirjayesh I'll do math for you, only 5.5 years! ...however helpful answer.
    – Cirelli94
    Commented Jun 28, 2017 at 14:06
  • 12
    success and error are being deprecated in jQuery 1.8. You should start using .done() and .fail(). See the documentation.
    – FibreChips
    Commented Jul 7, 2017 at 20:45
  • 4
    What are being deprecated are the callback-manipulation functions (e.g. .error, .success) not the parameters to the ajax method. See the comments in this thread. stackoverflow.com/a/10931891/4490454
    – EGS
    Commented Jan 2, 2018 at 9:21
  • 1
    @Mike: The thing is that you can't get the result out from the call unless you have a TARDIS. As the call is asynchronous, the result will arrive after the call returns. You can look into using promises provided in other answers here, which will let you return something from the call eventhough the result hasn't arrived yet. At some point you have to wait for the result anyhow, a promise just lets you do that in a different part of the code.
    – Guffa
    Commented Aug 3, 2019 at 22:42
226

you can add async option to false and return outside the ajax call.

function testAjax() {
    var result="";
    $.ajax({
      url:"getvalue.php",
      async: false,  
      success:function(data) {
         result = data; 
      }
   });
   return result;
}
8
  • 18
    You solution is perfectly valid. I just want to emphasize the importance of not returning the value right away inside the success callback, but outside of the .ajax function call. Otherwise you will get undefined. Commented Jul 11, 2013 at 11:56
  • 2
    is there any way to use this function with async:true ?
    – vivex
    Commented Mar 14, 2015 at 8:45
  • 17
    async: false is now deprecated in whatwg spec for most use cases. Google Chrome already warns about this in its console when a call occurs with async: false. w3c spec does not seem to have deprecated it yet.
    – Frédéric
    Commented Apr 30, 2015 at 19:45
  • why doesn't this work? function get_cmd_info3(cmd){ var result = null; $.get("bash/"+cmd, function(data) { console.log(data); result = data }, 'json'); return result; } Commented Apr 20, 2016 at 14:27
  • 1
    using async: false makes my code works, but takes some time to get the data. maybe that's why it is about to be ommitted. any solution for this? what's the proper way now?
    – kapitan
    Commented Jul 26, 2020 at 2:19
0

Idk if you guys solved it but I recommend another way to do it, and it works :)

    ServiceUtil = ig.Class.extend({
        base_url : 'someurl',

        sendRequest: function(request)
        {
            var url = this.base_url + request;
            var requestVar = new XMLHttpRequest();
            dataGet = false;

            $.ajax({
                url: url,
                async: false,
                type: "get",
                success: function(data){
                    ServiceUtil.objDataReturned = data;
                }
            });
            return ServiceUtil.objDataReturned;                
        }
    })

So the main idea here is that, by adding async: false, then you make everything waits until the data is retrieved. Then you assign it to a static variable of the class, and everything magically works :)

1
-14

See jquery docs example: http://api.jquery.com/jQuery.ajax/ (about 2/3 the page)

You may be looking for following code:

    $.ajax({
     url: 'ajax/test.html',
     success: function(data) {
     $('.result').html(data);
     alert('Load was performed.');
   }
});

Same page...lower down.

1
  • 1
    NO What if the result is needed in further processing inside another function ?, how are you going to pass it there ?
    – Eyad Bereh
    Commented Aug 3, 2021 at 7:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.