Syncronous AJAX stops on Error - javascript

I do have AJAX request and in the success callback new function to rendergooglelinks and another AJAX calls are called.
And now, I try to change the asyncronous calls to syncronous using async: false in the AJAX request.
When I do a AJAX request, rendergooglelinks are not rendered due to "undefined" error and next ajax request works.
In the syncronous ajax request, progress stops after rendergooglelinks error. Next calls are not triggered.
(i.e) Codes after that error are not processed.
Whether syncronous ajax request stops on errors ?
Whether it behaves in the way of "strict" mode ?
How can we handle this ?
// syncronous request
$.ajax({
type:"GET",
async: false,
url: url,
success: function(result, status, xhr) {
rendergooglelinks();
renderComments(); // this is not called due to error in the above
}
});
function rendergooglelinks()
{
google.test = ''; // returns error
}
function renderComments()
{
// asyncronous request
$.ajax({
type:"GET",
url: url,
success: function(result, status, xhr) {
}
}
});

Based on the code you posted, the error is that the variable google is never declared, so google.test cannot be assigned.
On the other hand, synchronous ajax calls are not a good practice, avoid them if possible.
Last but not last from jQuery.ajax() docs:
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
For the google variable, i suggest you to pass it to the function as argument, is dangerous to assume that it exist no matter what.
For other errors, try this:
$.ajax({
type:"GET",
//async: false,
url: url,
/*success: function(result, status, xhr) {
rendergooglelinks();
renderComments(); // this is not called due to error in the above
}*/
}).then([ //success callbacks
rendergooglelinks,
renderComments
],[
//no fail callbacks
]);
function rendergooglelinks(){
google.test = ''; // returns error
}
function renderComments(){
// asyncronous request
$.ajax({
type:"GET"
url: url,
/*success: function(result, status, xhr) {
}*/
}).done(function(result, status, xhr){
});
}
See also jQuery Deferred

Related

Ajax Request sometimes causes `XHR failed loading: POST` error

I am trying to run a simple Ajax Request to pass a JSON object from my Javascript file to my Python file in Django. However half the time, I get the error XHR failed loading: POST when I run it as follows:
var csrf = $("[name=csrfmiddlewaretoken]").val()
$.ajax({
type: "POST",
url: "/fridge",
data: {
"fridgeitems": JSON.stringify(fridge),
"csrfmiddlewaretoken": csrf
},
dataType: "json",
timeout: 5000,
}).done(function(data) {
console.log(data.fridge);
}).fail(function(jqXHR, status) {
alert('Request could not complete' + status);
});
})
// rest of code
In my python file:
fridgeitems = request.POST['fridgeitems']
# do something with the data
response_data = json.dumps(fridgeitems)
return JsonResponse({"fridge": fridgeitems}})
I think what is happening is that when the Ajax request is placed the rest of the code runs, finishes and quits the function before ajax call has time to load. I have tried including timeout in my Ajax call however this appears to do nothing. How can I make the function wait for the Ajax call to finish?
Your problem is most likely that your request is timing out after a while of not getting response from the server. One likely cause is due to a slow network.
To handle this, do either or both of two things:
1. Handle the case where an request doesn't complete with the fail() method of the jqXHR object.
2. Include a timeout in the ajax request settings.
I illustrate using the combined strategy below:
var csrf = $("[name=csrfmiddlewaretoken]").val();
$.ajax({
method: "POST",
url: "/fridge",
data: {
"fridgeitems": JSON.stringify(fridge),
"csrfmiddlewaretoken": csrf,
},
dataType: "json",
timeout: 5000 // 5000ms
}).done(function(data) {
// is called if request is successful
console.log(data.fridge);
}).fail(function(jqXHR, status) {
// is called if request fails or timeout is reached
alert('Request could not complete: ' + status);
});
Notice, the use of the jQuery deferred objects methods: done() and fail() instead of sucess() and error(). The later is deprecated.

Error or fail not being reached when Ajax fails to fetch JSON

I am working on below Ajax code in JavaScript, I am trying to pop up a dialog box when the URL could not load the JSON properly the reason may be either expired token or incorrect token, in any case, I am expecting the code to hit the error or fail but it's not happening. When the URL could load the JSON successfully, success and complete blocks are being hit as expected but nothing is being hit when URL fails. I have tried to use async: false and tried to check with a boolean variable weHaveSuccess but console.log(weHaveSuccess); which is in the last line of the code is getting executing even before success/error is being executed and it seems to me like its still loading asynchronously. I would like to know why error block is not being hit when the JSON load from URL is getting failed.
My code
function checkUser(myURL, newAccessToken, weHaveSuccess) {
$.ajax({
type: "GET",
dataType: "jsonp",
async: false,
url: myURL + newAccessToken,
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log("Status: " + textStatus);
console.log("Error: " + errorThrown);
},
success: function (data) {
console.log("Hello 2 " + JSON.stringify(data));
weHaveSuccess = true;
console.log('Message from Success ' + weHaveSuccess);
},
complete: function () {
console.log('Message from Complete ' + weHaveSuccess);
}
}).done(function (data) {
alert("Success");
console.log(data);
}).fail(function (data) {
console.log(data);
alert("Failed");
}).always(function () {
alert("In Always");
});
console.log(weHaveSuccess);
}
Thanks in advance!
AJAX requests are asynchronous. It takes time for a remote request to be made and responded to. You will have to write your post-response code within the success function or call another function from there, not within the same scope as where the call is initiated.
I am taking a bit of a guess here about what your server returns on failure. An AJAX request success means simply that a 200 OK response was received, without any consideration of the contents of the data. If an error is simply a change in the data you will need do one of the following to show an error:
Have the server set a status code header on failure, perhaps 400 Bad Request.
In the success function look within your data for whatever error response you are expecting and trigger the alert() there.
First of all the console.log(weHaveSuccess); fires first, because the $.ajax() is asynchronous while console.log is not so ajax will be triggered and return the promise when finishes, but the browser will continue with the script.
In the jQuery ajax docs says:
Cross-domain requests and dataType: "jsonp" requests do not support
synchronous operation.
It's hard to debug without seeing the response, maybe you can add some info from the network or a URL?
How about if you try the following:
Add the jsonp setting to your $.ajax() function for the callback that will handle the response and console.log there:
function myCallback(data) {
console.log(data);
}
$.ajax({
type: "GET",
dataType: "jsonp",
jsonp: myCallback,
...

How to call code-behind method from 'success' in ajax callback?

How to modify below code to use 'success' to call testMethod() in code-behind ?
I need to wait for return value from testMesthod() and process it.
$.ajax( {
url : 'myPage.aspx/testMethod',
type : "POST",
contentType : "application/json; charset=utf-8",
data : "{'name':'" + aNb + "'}",
dataType : "json"
}).done(function() {
alert("ok");
}).fail(function() {
alert("not ok");
});
Above code does not work because somehow latest JQuery version (1.10.1) gets overwritten by 1.3.2.
Thank you
You would need to pass the callback function to the function that wraps your $(ajax).
function getData(ajaxQuery, callBack){
var ajaxHREF = 'your url';
$.ajax({
url: ajaxHREF,
type: "post",
data: ajaxQuery,
beforeSend: function ( xhr ) {
xhr.overrideMimeType("application/json");
},
success: function(response, textStatus, jqXHR){
var jsonData = $.parseJSON(response);
callBack (jsonData);
},
However, a much better way of doing this is the global success event. It is better because you have all of the properties of the call available to you to enable dynamic processing of the results. Create the global success event inline = $(document).ajaxSuccess this gets called for all jquery ajax success events so you need to differentiate which calls apply to your specific handler (to each global handler).
$(document).ajaxSuccess(function(event, xhr, settings) {
var query = settings.data;
var mimeType = settings.mimeType;
if (query.match(/ameaningfulvalueforthishandler/)){
if(mimeType.match(/application\/json/)){
var jsonData = $.parseJSON(xhr.responseText);
}
}
}
Thank for replies, but I still do not see how callbacl can help me.
I need to call webmethod in code-behind: testMethod()
Ajax call does it, url = "myPage.aspx/testMethod" will 'call' webmethod testMethod(),
but it's asynchronous and returns quickly into 'success' section of ajax call.
But, I need to Wait for testMethod() to finish processing, retrieve result returned by testMethod() and process it.
Asynchronous ajax will return us into 'success' without waiting for testMethod() to finish,
and we will not get any data in response.
So, how callback helps me to achieve it?
function getData(ajaxQuery, callBack){
var ajaxHREF = "myPage.aspx/testMethod";
$.ajax({
url: ajaxHREF,
type: "post",
data: ajaxQuery,
beforeSend: function ( xhr ) {
xhr.overrideMimeType("application/json");
},
success: function(response, textStatus, jqXHR){
var jsonData = $.parseJSON(response);
callBack (jsonData);
});
Thank you
#Karen Slon - If I understand the question correctly, I think you need to conceptually separate the client side from the server side. The callback in .success/.done or global ajaxSuccess event enable your web page to initiate the request and keep on processing while the server side is processing your request 'myPage.aspx/testMethod'. When it completes successfully it returns to the success event. Now if testMethod does not return anything then you will find yourself in the success event event without a result. But you cannot get there unless web method testMethod has completed successfully and returned control. The .done event in your example only has alert("ok");. What makes you believe that the web method testMethod is not complete when the .done event occurs?
Look at these posts for better examples:
jQuery.ajax handling continue responses: "success:" vs ".done"?
http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
http://api.jquery.com/category/deferred-object/

Is there any analog to a 'finally' in jQuery AJAX calls?

Is there a Java 'finally' analogue in jQuery AJAX calls? I have this code here. In my always I throw an exception, however I ALWAYS want it to go to the then() method.
call.xmlHttpReq = $.ajax({
url : url,
dataType : 'json',
type : 'GET'
}).always(function(processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
throw "something";
}).then(function() {
alert("i want to always run no matter what");
});
I have tried to use done(), complete(), and the another always(), but nothing seems to work.
Here is JSFiddle :
http://jsfiddle.net/qv3t3L0m/
See this example:
$.ajax({
type: "GET",
dataType: dataType,
contentType: contentType,
async: TRUE,
url: $('html form:nth-child(1)').attr('action') + "?" $('html form:nth-child(1)').serialize(),
success: function(data) {
console.log("FUNFOU!");
},
error: function(data) {
console.log("NÃO FUNFOU!");
},
complete: function(data) {
console.log("SEMPRE FUNFA!");
//A function to be called when the request finishes
// (after success and error callbacks are executed).
}
});
For more informations: http://api.jquery.com/jquery.ajax/
.always() should work. See the The jqXHR Object section at http://api.jquery.com/jQuery.ajax/.
jqXHR.always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { });
An alternative construct to the complete callback option, the
.always() method replaces the deprecated .complete() method.
In response to a successful request, the function's arguments are the
same as those of .done(): data, textStatus, and the jqXHR object. For
failed requests the arguments are the same as those of .fail(): the
jqXHR object, textStatus, and errorThrown. Refer to deferred.always()
for implementation details.
See also http://api.jquery.com/deferred.always/
The below suggestions will not work in jQuery, because jQuery's promise implementation does not handle errors thrown in methods passed to then. I am only leaving them here as an illustration of what could be possible if jQuery was promises/A+ compliant. As Bergi rightly points out, you will have to manually wrap your code in your own try catch block.
call.xmlHttpReq = $.ajax({
url : url,
dataType : 'json',
type : 'GET'
}).then(function(processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
throw "something";
}).always(function() {
alert("i want to always run no matter what");
});
Although I'm not sure if jquery's promise supports always, an alternative would be to use then (again) and pass the same function as both successHandler and errorHandler, like this :
call.xmlHttpReq = $.ajax({
url : url,
dataType : 'json',
type : 'GET'
}).then(function(processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) {
throw "something";
}).then(function() {
alert("i want to always run no matter what");
},
function() {
alert("i want to always run no matter what");
});
Just a note for those who use jQuery 3.0 and later
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
As in official documentation
There is a bug ajax is dependent on the server, need to check status with "complete" is the best, a kind of "success", "error" and others are not 100% of the PUT, POST and GET ... look at an example
$.ajax({
url: '/api/v2/tickets/123456.json',
....
....
....
complete: function(data) {
if (data.statusText == "success") {
console.log("Sent successfully");
} else {
console.log("Not Sent");
}
}
});
Sorry bad english! Cheer ;-)
if you want one code definition for all ajax requests, you can do it like this
$(document).ajaxComplete(function () {
console.log('ajax complete on doc');
})

use paging with ajax call in a while loop

In a javascript function I make a call to the server and get batches of 10 records back. I need to do this untill I've had all records.
To start I made a while loop where in the error callback of the ajax call I would end the while loop.
Halfway through I started to realize that that would not work, as the ajax call is async and I would thus fire loads of requests in the loop. I'm sure there is a standard pattern to do this but I don't know how.
How can I do the ajax call in a loop and perform it as long as the call is not returning an error?
Pseudo code I was building:
var stillRecordsAvailable = true;
while (stillRecordsAvailable) {
// get the next batch of records
$.ajax({
url: '/getrecords.json',
data: {data_set_id: dataset.id},
type: 'GET',
success: function(data, textStatus, xhr) {
// do something
},
error: function(xhr, textStatus, errorThrown) {
// nothing left to do
stillRecordsAvailable = false;
}
});
Thanks for pointing me in the right direction
You'd probably want to just wrap the ajax call in a function that is called on the ajax success callback:
function getRecords(data, textStatus, xhr) {
if (data) {}; // do something...
$.ajax({
url: '/getrecords.json',
data: {data_set_id: dataset.id},
type: 'GET',
success: getRecords
});
}
This will only work if your server/API returns an error when no more records exist; however, this may not be the best pattern. A more elegant way of tracking asynchronous event state is through a deferred/promise pattern. jQuery has a great implementation: http://api.jquery.com/category/deferred-object/

Categories

Resources