9

I must be making a silly mistake but I cannot return the data I get from a $.post function and store it in a variable, not only that, I cannot return ANYTHING from within that function. Example:

function test(){

$.post("demo_test_post.asp",
    {
      name:"Donald Duck",
      city:"Duckburg"
    },
    function(data,status){
      return(data)
    });

}

var foo = test()
alert(foo)

it say's that foo is undefined. But to take it a step further, even when I do this:

function test(){

    $.post("demo_test_post.asp",
        {
          name:"Donald Duck",
          city:"Duckburg"
        },
        function(data,status){

          var bar = "bar"
          return(bar)
        });

    }

    var foo = test()
    alert(foo)

it STILL says foo is undefined... I must be doing something wrong or misunderstanding something. Can someone please help.

Thanks

Sam Creamer
  • 5,187
  • 13
  • 34
  • 49
  • You're closing your `$.post()` function at the end of that `function()`, instead of after the last `}`. – ayyp Jun 07 '13 at 15:32
  • so the `);` should be at the last `}` ? edit: doing that seemed to stop the function all together I think I misunderstood – Sam Creamer Jun 07 '13 at 15:33
  • possible duplicate of [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Felix Kling Jun 07 '13 at 15:35
  • @SamCreamer - apart from missing a few semicolons your code is valid. However, Blade0rz's answer explains why it isn't working as expected. – Joe Jun 07 '13 at 15:37
  • You can't access the data effectively outside of a callback. Just accept that. If you want to use the data, use it in side of a callback of some form, such as the success/done callback. you can't return it from a function because you don't know when it will be available. – Kevin B Jun 07 '13 at 15:48

6 Answers6

16

$.post is a asynchronous function. The control from function will immediately return after it run post but the response from post may be received later.

So what you can do is instead of return, use a call back function and define callback function outside.

say,

function test(){

  $.post("demo_test_post.asp",
    {
      name:"Donald Duck",
      city:"Duckburg"
    },
    function(data,status){
      my_function(data)
    });

}

function my_function(data){
  // you can operate on data here
}
Nagarjun
  • 2,346
  • 19
  • 28
  • 1
    THIS is a beautiful solution to my problem, thank you. And thank you to everyone else for all of the answers I have learned a lot about AJAX in the last 5 minutes – Sam Creamer Jun 07 '13 at 15:41
  • But now my goal is to get the variable `data` into a variable outside of the function ,is this possible – Sam Creamer Jun 07 '13 at 15:43
  • Yes, you are passing data as parameter to the function my_function so it can be used without any issue. – Nagarjun Jun 07 '13 at 15:44
  • 3
    Note, you can do `$.post("demo_test_post.asp",{name:"Donald Duck",city:"Duckburg"},my_function);`, no need for the extra anonymous function. – Kevin B Jun 07 '13 at 15:47
  • lets say I want to make a var called `myVar` and access it outside of both of these functions and the var contained `data` how would I accomplish that? – Sam Creamer Jun 07 '13 at 15:47
  • define that variable outside both functions in your javascript file, that variable now become global variable and accessible in both functions or others as well. However do not create too many such global variables which will pollute the global namespace. – Nagarjun Jun 07 '13 at 15:53
4

You don't return anything from post(). What you have inside function(data, status) {} is actually a callback and doesn't return a result to the post() method like you think.

Have a read of the this article for more information

CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
4

A jQuery post() is by default Asynchronous meaning that you can never return a value from a function like this.

To Quote the jQuery Docs

async (default: true)

Type: Boolean

By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false.

You would need to provide a callback function in order to update the value.

e.g. A very basic example.

var foo;
test();    

function test(){    
    $.post("demo_test_post.asp",
        {
          name:"Donald Duck",
          city:"Duckburg"
        },
        function(data,status){

          var bar = "bar"
          foo = bar; // assign foo

        });    
    }    
}

Alternatively you can look at changing your jQuery Ajax to be Synchronous. Take a look at this post here How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

Community
  • 1
  • 1
Tim B James
  • 20,084
  • 4
  • 73
  • 103
4

Try using the .done() to execute the returned data. This should ensure that it gets the data and doesn't set your variable or alert data before it finishes.

$.post("demo_test_post.asp", { name: "Donald Duck", city: "Duckburg" })
.done(function(data) {
  alert("Data Loaded: " + data);
  //Or return data;
});
Dylan N
  • 527
  • 3
  • 13
2

jQuery AJAX requests are made asynchronously, meaning that the request is started and the $.post() method returns more or less immediately. The request is processed by the browser in the background. When the request is completed, jQuery calls the callback function you supplied to $.post(). You can use async: false to tell jQuery to block until the request completes, but this is not recommended as it will almost certainly result in terrible performance and a poor user experience.

What you should do instead is write your code such that the logic that depends on the AJAX response is kicked off by your callback function. Something like:

function handleAjaxResponse(responseData) {
  // do something with the response.
}

function doAjax() {

  $.post("demo_test_post.asp",
    {
      name:"Donald Duck",
      city:"Duckburg"
    },
    function(data, status){
      handleAjaxResponse(data);
    });

}

doAjax();
Annabelle
  • 10,596
  • 5
  • 27
  • 26
  • This is a good answer, but I respectfully disagree with your blanket condemnation of `async:false`. It all depends on how you are using the function. For example, if ajax is being used only to prevent screen refresh, and the data is returned quickly via ajax, then using `async:false` can be used to improve the user experience. – cssyphus Jun 07 '13 at 15:50
  • @gibberish: If the UI should block, I think a better solution is to overlay a blocker div with a loading/processing indicator. Otherwise, the user is left with an unresponsive UI (e.g. buttons that won't click, checkboxes that won't check) and no indication why. – Annabelle Jun 07 '13 at 16:05
1

You are using the more streamlined .post() method. This is both more finicky to work with (IMHO) and somewhat less powerful than the larger form, $.ajax().

Personally, I have found the .ajax() method to be preferable because the added structure makes it easier to format. Also, you can do more with .ajax (there are more options, such as turning off asynch which is sometimes very useful when you want to delay processing until the data has been returned).

Here is a simple example of using the full $.ajax() method. Note the success function at the bottom -- that is where you can use the data sent back from the other PHP file!

Community
  • 1
  • 1
cssyphus
  • 37,875
  • 18
  • 96
  • 111