I have the following json ajax call:
$.getJSON(server_data.secure_api+'/e/account/check/?callback=?', queryData,
function(data) {
has_error = (data.status == 'failure');
});
Which works perfectly, except that it is asynchronous. I now need to make it synchronous, because I need to pause the calling function until has_error is set. How do I do this?
I have already tried using a .ajax call, like this:
jQuery.ajax({
url: server_data.secure_api+'/e/account/check/?callback=?',
data: queryData,
DataType: 'jsonp',
success: function(result) {
has_error = (data.status == 'failure');
},
async: false
});
But it doesn't work! I've tried setting the DataType to json, jsonp, or not set; I've tried including the ?callback=? and I've tried leaving it off; none of this has worked. What am I doing wrong?
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. Cross-domain requests and dataType: "jsonp" requests do not
support synchronous operation. Note that synchronous requests may
temporarily lock the browser, disabling any actions while the request
is active.
As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding method
http://api.jquery.com/jQuery.ajax/
There's no reason your use case should require synchronous code. If you need some code to delay it's execution until the asynchronous call is completed then place that code in the callback function.
Related
GOAL: What I'm after is to get data from database and refresh main.php (more evident through draw_polygon) every time something is added in database (after $.ajax to submit_to_db.php).
So basically I have a main.php that will ajax call another php to receive an array that will be saved to database, and a json call another php to return an array will be used by main.php.
$(document).ready(function() {
get_from_db();
$('#button_cancel').click(function(){
$.ajax({
url: 'submit_to_db.php',
type: 'POST',
data: {list_item: selected_from_list},
success: function(result){
...
get_from_db();
}
});
});
function get_from_db(){
$.getJSON('get_from_db.php', function(data) {
...
draw_polygon(data);
});
}
});
In my case, what I did was a get_from_db function call for getJSON to actually get data from database, with the data to be used to draw_polygon. But is that how it should be done? I'm a complete newbie and this is my first time to try getJSON and ajax too to be honest. So my question: How does asynchronous work actually? Is there another workaround for this instead of having to call function get_from_db with getJSON (it isn't synchronous, is it? is that why it doesn't update the page when it isn't within a function?) All the time - like $.ajax with async: false (I couldn't get it to work by the way). My approach is working, but I thought maybe there are other better ways to do it. I'd love to learn how.
To make it more clearer, here's what I want to achieve:
#start of page, get data from database (currently through getJSON)
Paint or draw in canvas using the data
When I click the done button it will update the database
I want to AUTOMATICALLY get the data again to repaint the changes in canvas.
Since $.getJSON() uses ajax configurations, just set the global ajax configs:
// Set the global configs to synchronous
$.ajaxSetup({
async: false
});
// Your $.getJSON() request is now synchronous...
// Set the global configs back to asynchronous
$.ajaxSetup({
async: true
});
Asynchronusly does mean the Request is running in the background, and calls your function back when it got a response. This method is best if you want to have a result but allow to use your app within the request. If you want to have a direct response, take a look at a synchron request. this request will pause script execution until it got a response, and the user can not do anything until the response was recieved. You can toggle it via:
async: false,
So for example:
$.ajax({
url: "myurl",
async: false,
...
})
$.getJSON(), doesn't accept a configuration, as it says in the docs it's a shorthand version of:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
So just rewrite your request in terms of that and async:false will work just as you expect.
$.getJSON() is a shorthand notation for $.ajax() which can be configured to be synchronous (see jQuery.getJSON and JQuery.ajax):
$.ajax({
dataType: "json",
url: url,
data: data,
async: false,
success: function(data) {
...
draw_polygon(data);
}
});
Try to avoid synchronous calls though. Quote from jQuery doc (see async prop):
Cross-domain requests and dataType: "jsonp" requests do not support
synchronous operation. Note that synchronous requests may temporarily
lock the browser, disabling any actions while the request is active.
You might want to try jQuery Deferreds like this:
var jqxhr = $.getJSON(url);
jqxhr.done(function(data) {
...
draw_polygon(data);
});
I created a ajax function for uploading file images, everything works except there's an ugly part where the page freezed at the process (ajax file image processing submission), any ideas, help, suggestions, clues? below is my code reference.
$("#form_image_file_submit").submit(function(e){
var this_current = $(this);
var formData = new FormData(this_current[0]);
$.ajax({
url : this_current.attr("action"),
data: formData,
type: 'post',
cache: false,
async: false,
complete: function(data){
alert(data);
}
});
You have async: false. Change it to true
Use async:true or remove it.
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. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success().
Ajax Docs
I am facing a serious issue... Whenever i use Ajax to send a request and get an response my browser got hanged.. and show no loading etc...
But when i response is retrieved from the Ajax then browser and page again start working...
Below is the code that i used.....
function ShowContestStatus(contestID)
{
$("#showContestDetails").html('<div class="loadercontest"><img src="assets/images/loading.gif">Loading Contest....</div>');
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', true);
$.ajax({
url:"process/processMyContest.php",
type:'POST',
cache:false,
async:false,
data : {act : 'showcontest', cid : contestID },
success:function(result)
{
$("#showContestDetails").html(result);
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', false);
}
});
}
Please help me on this... i want to get the same response as on other websites when you send a request and they are using ajax the page neither hanged and also each processing like scrolling etc is visible ......
So please suggest me good ideas.... so i can get rid of it and make my ajax smooth for page without effecting and irritate the other person by hanged...
Thanks in advance...:)
The problem is async:false... Since your ajax request is synchronous the script execution will wait for the request to complete to continue..
Since browser uses a single threaded execution pattern(either it will execute script or repaint or wait for user events at a time- not all at the same time), your browser tab will stop listening to user(so it will look like it is hanged)
function ShowContestStatus(contestID) {
$("#showContestDetails").html('<div class="loadercontest"><img src="assets/images/loading.gif">Loading Contest....</div>');
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', true);
$.ajax({
url: "process/processMyContest.php",
type: 'POST',
cache: false,
//remove async: false,
data: {
act: 'showcontest',
cid: contestID
},
success: function (result) {
$("#showContestDetails").html(result);
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', false);
}
});
}
Ajax.async
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. Cross-domain requests and dataType: "jsonp" requests do not
support synchronous operation. Note that synchronous requests may
temporarily lock the browser, disabling any actions while the request
is active. As of jQuery 1.8, the use of async: false with jqXHR
($.Deferred) is deprecated; you must use the success/error/complete
callback options instead of the corresponding methods of the jqXHR
object such as jqXHR.done() or the deprecated jqXHR.success().
Make async:true for making the browser listen other events while running the ajax code.
I'm trying to use JQuery although i'm struggling to successfully wait for a ajax call to succeed before executing further code. Is there a way to wait for an ajax to call? I've seen examples but it seems just to wait blindly for x amount of seconds?
Thanks,
James
Yes, you can do request synchronously:
var bodyContent = $.ajax({
url: "script.php",
global: false,
type: "POST",
data: {id : this.getAttribute('id')},
dataType: "html",
async:false,
success: function(msg){
alert(msg);
}
}
).responseText;
Source: http://api.jquery.com/jQuery.ajax/
However, synchronous requests are a step backwards, as the JS engine (and, in some browsers, the user interface) will block until the request completes. Douglas Crockford once wrote about synchronous requests:
Synchronous programming is disrespectful and should not be employed in applications which are used by people.
Have a look at jQuery deferreds. You can't halt this, but you can call other code after an AJAX call returns.
// No way to stop.
$.ajax(...);
doSomething();
But with deferds you can:
$.ajax(...).success(function() {
doSomething();
});
See this article.
http://www.erichynds.com/jquery/using-deferreds-in-jquery/
Use async: false
or use a callback function
You can use success or complete callbacks. Success fires if the server returns a 200. Complete will fire when the request is finished, regardless of the response status.
$.ajax({
url: "/path/to/action",
success: function() {
alert("do something if it's successful");
},
complete: function(request, status) {
alert("do something when it's finished, regardless of success.");
}
});
or you can do a synchronous call:
$.ajax({
url: "/path/to/action",
async: false
});
jQuery's ajax methods have a success handler.
You should put your code that you want to fire on success in a method attached to this handler.
Consider the example given on the jQuery website:
$.ajax({
url: "test.html",
context: document.body,
success: function(){
$(this).addClass("done");
}
});
You can see here that there's a success handler with a method attached. This method will execute when the ajax method returns succesfully.
As has been pointed out in other answers and the comment below, you can now use deferreds instead of this simple success handeler. This allows you to attach multiple actions to each given event.
You have to insert your code in the 'success' function: http://api.jquery.com/jQuery.ajax/
Why don't return that function the responseText?
function LoadBookmarksAsXml()
{
return $.ajax(
{
type: 'GET',
async: false,
url: 'http://www.google.com/bookmarks/?output=xml&num=10000'
}).responseText;
}
(It works if I define a success-callback-function and set async to true!)
Thanks in advance!!
Edit: Don't worry about the cross-domain call; user603003 says (in a comment on a now-deleted answer) that this is in a Chrome extension where cross-domain requests are allowed.
The solution if someone wants to do the same:
return $.ajax(
{
type: 'GET',
async: false,
url: 'http://www.google.com/bookmarks/?output=xml&num=10000',
});
(You will get a XMLHTTPRequest object.)
I'm not immediately seeing why it's not returning it, but I'd still use a success callback:
function LoadBookmarksAsXml()
{
var result;
$.ajax(
{
type: 'GET',
async: false,
url: 'http://www.google.com/bookmarks/?output=xml&num=10000',
success: function(data) {
result = data;
}
});
return result;
}
Even though $.ajax returns an XMLHttpRequest object (in 1.4 or earlier) or a jqXHR object (in 1.5+), I'd still prefer using a success function and an error function for clarity. Also, different versions of jQuery give you different values for responseText on error (at least on Chrome; 1.4.4 returns an empty string, 1.5.0 returns undefined).
If there's any way you can avoid it, avoid it. Synchronous requests completely lock up the UI of most browsers (not just your page's UI, every page in every tab that browser is managing). Since ajax requests can take a second or two (or five, or ten), this makes for a very unpleasant user experience. Nearly all the time, you can avoid it by refactoring your function so it accepts a callback to use to supply the result:
function LoadBookmarksAsXml(callback)
{
$.ajax(
{
type: 'GET',
url: 'http://www.google.com/bookmarks/?output=xml&num=10000',
success: function(data) {
callback(data);
},
error: function() {
callback(null);
}
});
}
Off-topic: I'll be surprised if the request works at all, though, because on the face of it (unless you work for Google), that request will fail because of the Same Origin Policy. Various ways to get around the SOP:
JSONP
CORS (but it requires browser support and that www.google.com allow the request from your origin)
Using YQL as a proxy
$.ajax never returns the response text, it always returns the XMLHTTPRequest object created to make the Ajax call.
You'll still need to define a success callback I think, e.g. one setting a local variable which you can then return.
Standard disclaimer: Synchronous requests are a usually discouraged practice because they can freeze the current page.
Waiting for the response of a function is not asyncronous, the ajax call will have a response when it is done, you have to take care of the response then, by defining callbacks for the successful event.
You have ti break up your code to at least two parts. First part is before the ajax call, second part is after the success, and put everything you want to do with the requested data in the success callback. Asyncronous requests work this way.
Doing that is a really bad idea. Javascript will block for the duration of the HTTP request, which is to say nothing else in the UI thread will run until the ajax call returns. Use a callback.
By design, asynchronous requests can't deliver a responseText out of the blue ;-)
You HAVE to set a callback function and decide how you will handle the responseText.