JavaScript: Global variables after Ajax requests

JavascriptJqueryAjaxGlobalSynchronous

Javascript Problem Overview


the question is fairly simple and technical:

var it_works = false;

$.post("some_file.php", '', function(data) {
										
     it_works = true;

});

alert(it_works); # false (yes, that 'alert' has to be here and not inside $.post itself)

What I want to achieve is:

alert(it_works); # true

Is there a way to do that? If not can $.post() return a value to be applied to it_works?

Javascript Solutions


Solution 1 - Javascript

What you expect is the synchronous (blocking) type request.

var it_works = false;

jQuery.ajax({
  type: "POST",
  url: 'some_file.php',
  success: function (data) {
    it_works = true;
  }, 
  async: false // <- this turns it into synchronous
});​

// Execution is BLOCKED until request finishes.

// it_works is available
alert(it_works);

Requests are asynchronous (non-blocking) by default which means that the browser won't wait for them to be completed in order to continue its work. That's why your alert got wrong result.

Now, with jQuery.ajax you can optionally set the request to be synchronous, which means that the script will only continue to run after the request is finished.


The RECOMMENDED way, however, is to refactor your code so that the data would be passed to a callback function as soon as the request is finished. This is preferred because blocking execution means blocking the UI which is unacceptable. Do it this way:

$.post("some_file.php", '', function(data) {
    iDependOnMyParameter(data);
});

function iDependOnMyParameter(param) {
    // You should do your work here that depends on the result of the request!
    alert(param)
}

// All code here should be INDEPENDENT of the result of your AJAX request
// ...

>Asynchronous programming is slightly more complicated because the consequence >of making a request is encapsulated in a function instead of following the request statement. But the realtime behavior that the user experiences can be significantly >better because they will not see a sluggish server or sluggish network cause the >browser to act as though it had crashed. Synchronous programming is disrespectful >and should not be employed in applications which are used by people.

Douglas Crockford (YUI Blog)

Solution 2 - Javascript

AJAX stands for Asynchronous JavaScript and XML. Thus, the post to the server happens out-of-sync with the rest of the function. Try some code like this instead (it just breaks the shorthand $.post out into the longer $.ajax call and adds the async option).

var it_works = false;

$.ajax({
  type: 'POST',
  async: false,
  url: "some_file.php",
  data: "",
  success: function() {it_works = true;}
});

alert(it_works);

Hope this helps!

Solution 3 - Javascript

It seems that your problem is simply a concurrency issue. The post function takes a callback argument to tell you when the post has been finished. You cannot make the alert in global scope like this and expect that the post has already been finished. You have to move it to the callback function.

Solution 4 - Javascript

The reason your code fails is because post() will start an asynchronous request to the server. What that means for you is that post() returns immediately, not after the request completes, like you are expecting.

What you need, then, is for the request to be synchronous and block the current thread until the request completes. Thus,

var it_works = false;

$.ajax({
  url: 'some_file.php',
  async: false,  # makes request synchronous
  success: function() {
    it_works = true;
  }
});

alert(it_works);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGalView Question on Stackoverflow
Solution 1 - JavascriptgblazexView Answer on Stackoverflow
Solution 2 - JavascriptmattbastaView Answer on Stackoverflow
Solution 3 - JavascriptHosam AlyView Answer on Stackoverflow
Solution 4 - JavascriptJesse DhillonView Answer on Stackoverflow