jQuery: Return data after ajax call success [duplicate]
Asked Answered
C

5

542

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; 
}
Cwmbran answered 15/3, 2011 at 19:8 Comment(1)
this may help you . codingbin.com/get-return-data-ajax-callIphlgenia
F
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.
Flavour answered 15/3, 2011 at 19:13 Comment(9)
I guess adding [success] status would delay some and more accurate to only call when status is 400 successful.Papillote
@iamsirjayesh I'll do math for you, only 5.5 years! ...however helpful answer.Actino
@Cirelli94: poor me at maths :pDandrea
success and error are being deprecated in jQuery 1.8. You should start using .done() and .fail(). See the documentation.Traverse
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. https://mcmap.net/q/74742/-should-i-use-done-and-fail-for-new-jquery-ajax-code-instead-of-success-and-errorSaberio
I know this is old but the calling part makes no sense to me. What if I wanted to store the "output" to a variable to be used in a conditional statement. "Here you use the output doesnt make much sense to me. I would like to just get the value out of the call to the testAjax functionKeefe
@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.Flavour
var res = testAjax(function(output){ return(output); }); not working !!!!!Fenny
@Flavour can you help me out here #70286458Intestine
W
454

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:

Witherite answered 15/3, 2011 at 19:19 Comment(9)
They are just messing around with ajax, seeing how it works.Outroar
Perfect answer!Just to add a side note for users, this will not work with jQuery ver 1.4.Protecting
This helped a lot. I just skipped on step var promise = testAjax() and did this testAjax().success(function (data) { alert(data); });Abusive
@Witherite great answer indeed! But I've followed your demo code, and it seems to call ajax twice (does anyone else noticed the same?).Cheyennecheyne
@Abusive by using your approach, the ajax is only called once (as I needed).Cheyennecheyne
Worth mentioning that Promises/A+ promises are in jQuery in the 3.0 branch.Opalina
How about multiple data variables? Like data.users, data.prices ?Epigeal
@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.Witherite
is there a full example of using async with jquery 3.X ajax call? I can't seem to find a proper(without something or another being deprecated) example (this is getting absurdly confusing)Superabound
F
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.
Flavour answered 15/3, 2011 at 19:13 Comment(9)
I guess adding [success] status would delay some and more accurate to only call when status is 400 successful.Papillote
@iamsirjayesh I'll do math for you, only 5.5 years! ...however helpful answer.Actino
@Cirelli94: poor me at maths :pDandrea
success and error are being deprecated in jQuery 1.8. You should start using .done() and .fail(). See the documentation.Traverse
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. https://mcmap.net/q/74742/-should-i-use-done-and-fail-for-new-jquery-ajax-code-instead-of-success-and-errorSaberio
I know this is old but the calling part makes no sense to me. What if I wanted to store the "output" to a variable to be used in a conditional statement. "Here you use the output doesnt make much sense to me. I would like to just get the value out of the call to the testAjax functionKeefe
@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.Flavour
var res = testAjax(function(output){ return(output); }); not working !!!!!Fenny
@Flavour can you help me out here #70286458Intestine
A
224

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;
}
Aardvark answered 25/10, 2011 at 15:33 Comment(8)
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.Twiddle
is there any way to use this function with async:true ?Wellchosen
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.Professionalism
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; }Moline
this didn't wrk for mi.. the result is coming as undefined in my return statement!Intelligible
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check xhr.spec.whatwg.orgPyridoxine
async: false, option is very important otherwise it throws undefined errorExpletive
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?Pinkerton
S
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 :)

Scottie answered 1/3, 2013 at 8:30 Comment(1)
This was already proposed in this answer (https://mcmap.net/q/73548/-jquery-return-data-after-ajax-call-success-duplicate). In general, making synchronous Ajax requests is not a good idea.Cyrille
O
-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.

Outroar answered 15/3, 2011 at 19:12 Comment(1)
NO What if the result is needed in further processing inside another function ?, how are you going to pass it there ?Polyhydric

© 2022 - 2024 — McMap. All rights reserved.