Async AJAX call not working with when and then - javascript

I have the following code:
function accessControl(userId) {
return $.ajax({
url: "userwidgets",
type: "get",
dataType: 'json',
data: {
userid: userId
}
});
};
var userWidgets = accessControl('1');
$.when(userWidgets).then(function (data) {
alert(data);
});
I don't want to make the function sync by adding the parameter async: false, but the alert isn't appearing at all, is there something wrong in my code? should I use another approach?

$.ajax returns a promise. So, it don't need to be wrapped in $.when again.
Use then directly on userWidgets as it is ajax instance.
userWidgets.then(function (data) {
alert(data);
}, function(e, status, error) {
console.log(error);
// For debugging
});
From jQuery Docs
jqXHR.then(function( data, textStatus, jqXHR ) {}, function( jqXHR, textStatus, errorThrown ) {});
Incorporates the functionality of the .done() and .fail() methods, allowing (as of jQuery 1.8) the underlying Promise to be manipulated. Refer to deferred.then() for implementation details.

I don't want to make the function sync by adding the parameter async: false, but the alert isn't appearing at all, is there something wrong in my code? should I use another approach?
Making the ajax call synchronous will not solve this problem. Your approach is fine.
As #Tushar has said in his answer you don't really need to use $.when since the $.ajaxcall returns a promise so you can chain .then callbacks onto it without using $.when. But this is not the reason why your .then callback is not being invoked.
The reason why your .then callback is not being called is because that ajax call is failing and the promise is being rejected. .then callbacks are only called when promises are resolved successfully, this fiddle verifies this statement.
You will need add failure logic to your code to handle failures in your ajax call like this:
var userWidgets = accessControl('1');
$.when(userWidgets).then(function (data) {
alert(data);
})
.fail(function(){
alert("should do something on failure");
});

Related

which one should be used in case of jquery ajax call, success/ error callback or done()/fail() chain function

sometimes even if the ajax call has returned error, it calls done() chain function rather than fail().
so confused whether to use success/error callback or done()/fail() chain function.
for eg which one is advisable 1 or 2?
$.ajax({
url: someurl,
success: function(){
//some code if ajax request is successful
},
error: function(){
//some code if ajax request fails
}
})
$.ajax({
url: someurl
}).done(function(){
//some code changes
}).fail(function(){
//some code changes
});
These are interchangeable ways of doing an AJAX call in jQuery. The second method you describe uses promises, whereas the first method handles successes/errors as options on the AJAX call.

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/

No error handling in jQuery AJAX call invoked

I'm trying to make the AJAX call bark and squick at me so I'm executing a totally wrong URL. For some reason, none of the methods that are supposed to do the barking och squicking is invoked.
What is the reason?
$.ajax({
url: "http://totally.wrong.url",
dataType: 'jsonp',
error: function () { alert("bark 1"); },
failure: function () { alert("bark 2"); }
})
.fail(function () { alert("squick"); })
.done(function () { alert("woof"); });
Of course, if I change the URL to point to the correct WCF service, I get an approving woof.
According to jQuery API, I should use fail and done syntax but I'll be fine either way.
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
Ajax with JSONP and Cross Site Requests won't trigger the error callback.
Look at the accepted answer in this question: jQuery Ajax 404 Handling
Hopefully this should explain what you need to make it work.
I don't know if failure is supposed to work but I always use "error" and "success" instead.
So try:
$.ajax({
url: "http://totally.wrong.url",
dataType: 'jsonp',
error: function () { alert("bark");},
success: function () { alert("woof");}
}
})
$.ajax({
url: "http://totally.wrong.url",
dataType: 'jsonp',
**error**: function () { alert("bark"); }
})
.fail(function () { alert("squick"); })
.done(function () { alert("woof"); });
error is the request fail callback function and not failure

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