Chaining AJAX handlers with jQuery Deferred - javascript

I just can't seem to get a handle on jQuery's $.Deferred handling of AJAX calls.
What I want to do is execute three AJAX calls, each of which performs some processing on the returned data. The success call of the third AJAX call requires that the processing from the first two calls be complete, but the order of the first two calls does not matter.
Here is my code, and a jsFiddle:
var firstAjax = $.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(1);
return jqXHR.promise();
}
);
var secondAjax = $.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(2);
return jqXHR.promise();
}
);
$.when(firstAjax, secondAjax)
.done(
$.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here that relies on the initialization of the first and second calls being complete
alert(3);
}
)
);
Sometimes, but not always, "3" is alerted before "1" and "2". I have no problem with performing the third AJAX call immediately but its done handler needs to execute last.

you can do
var firstAjax = $.getJSON('/echo/json/').done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(1);
return jqXHR.promise();
}
);
var secondAjax = $.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here based on the data
alert(2);
return jqXHR.promise();
}
);
$.when(firstAjax, secondAjax)
.done(function(){
$.getJSON('/echo/json/')
.done(
function(data, textStatus, jqXHR){
//do some initialization here that relies on the initialization of the first and second calls being complete
alert(3);
}
)
});
you miss the "function(){" on this line $.when(firstAjax, secondAjax).done(function(){
http://jsfiddle.net/ACBJs/1/

Related

Using $.when with Ajax requisitions

I want to execute some $.ajax() requisitions in a certain order, so I tried to use $.when like this:(just for testing)
$.when.apply(null,[ajaxRequisition1(),ajaxRequisition2()] ).then(function () {
console.log("Completed all requests.");
});
But it shoots the message on the console before the requisitions are done. Any suggestions?
Thanks
EDIT
Here are one of my requisitions. I'll post one, but the others are very similar, changing only some parameters.
code:
function ajaxRequisition1(){
$.ajax({
type:'GET',
crossDomain:true,
url:'http://www.myurl.com.br/api/my_php.php?callbackplat=?',
dataType:'jsonp',
data: {currency: $('#cur').val()},
beforeSend: function(){
$('#loading').css("display","block");
$('table[name=tb_latam]').css("opacity","0.01");
}
}).done(function(data){
console.log(data);
//HERE I BUILD A TABLE USING THE DATA RECEIVED.
$('#loading').css("display","none");
$('table[name=tb_latam]').css("opacity","1");
$('#tb_latam').append('<tr> <td data-nome="A-ACTIVE" class="column_st">'+'Active'+
'</td><td class="c_qtdA column_qtd">'+data.lat_qtdA+
'</td><td id="a2"class="a">'+data.lat_active+
'</td><td>'+data.lat_p_active+'</td></tr>');
$('#tb_latam').append('<tr> <td data-nome="I-INACTIVE" class="column_st">'+'Inactive'+
'</td><td class="c_qtdI column_qtd">'+data.lat_qtdI+
'</td><td class="i">'+data.lat_inactive+
'</td><td>'+data.lat_p_inactive+'</td></tr>');
$('#tb_latam').append('<tr> <td data-nome="R-REPLACED" class="column_st">'+'Replaced'+
'</td><td class="c_qtdR column_qtd">'+data.lat_qtdR+
'</td><td class="r">'+data.lat_replaced+
'</td><td>'+' - '+'</td></tr>');
})
.fail(function(data, textStatus, errorThrown){
alert("ERROR!.");
console.log(data);
console.log(textStatus);
console.log(errorThrown);
});
return false;
}
jQuery $.when() accepts deferred objects. While your ajaxRequisition returns a non deferred, $.when() will then return a resolved promise.
Try to change your code,
function ajaxRequisition1 () {
return $.ajax({
...
});
}
function ajaxRequisition2 () {
return $.ajax({
...
});
}
$.when.apply(null, [ajaxRequisition1(),ajaxRequisition2()]).done(function () {
console.log("Completed all requests.");
});
I believe you need to use .done(...).
Check this to learn the differences.
edit
As per the docs of jquery, if you pass NOT-a-promise to the .when(...) method, the .then(...) will get called automatically and treat the arguments you passed to .when(...) as already resolved promises, and also pass them to the .then(...)
So, the array you're passing have to be promises so that the .when(...) gets called at the correct time.
If a single argument is passed to jQuery.when() and it is not a Deferred or a Promise, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.
Check docs.
edit 2
I thought your ajaxRequisitions methods were already working. Here's the example from the docs to the .when(...) function
$.when( $.ajax( "test.aspx" ) ).then(function(
data, textStatus, jqXHR ) {
alert( jqXHR.status ); // Alerts 200
});
You need to update it so you can add the .apply(...), and have your ajaxRequisition... Methods return the Ajax call you need in each one.

About Form , Ajax

I have a HTML form with ID hello
and i have ajax like this
jQuery(document).ready(function($) {
$("#hello").submit(function(){
var $form = $(this);
var serializedData = $form.serialize();
request = $.ajax({
url: "/blog/ajaxphp/registration_check.php",
type: "post",
data: {formData:serializedData},
datetype: "JSON"
});
request.done(function (response, textStatus, jqXHR){
console.log("hellosss");
if(jQuery.parseJSON(response).success==undefined){
$form.unbind('submit').submit();
}else{
return false;
}
});
request.fail(function (jqXHR, textStatus, errorThrown){
console.log("error");
});
return false;
});
});
But Submit button is not working . i mean it is working if i pressit two times ..
It logs this
Uncaught TypeError: object is not a function in this line $form.unbind('submit').submit();
Question :
How do i make form enable submit when jQuery.parseJSON(response).success==undefined is true otherwise disable form to submit .
How do i disable ajax button while ajax process is being performed.
$("#hello").submit(function(){
return false; <-- You are exiting the function right away
//nothing runs here
Use evt.preventDefault();
$("#hello").submit(function(evt){
evt.preventDefault();
or if you really want to use return, but it at the BOTTOM.
Also the return false in an asynchronous Ajax call does nothing. It is impossible to return anything from an asynchronous call.
EDIT
and you have a typo
if(jQuery.parseJSON(response).sucess==undefined){ <-- that is not how you spell `success`
Double Edit, see if breaking it up into two parts work.
$form.unbind('submit');
$form.submit();

$.getJSON with in a foreach Loop over all input fields

i have a quick question. I want to iterate over all checked checkboxes and parse the json files for the checked ones.
Here is my problem: The $().each function is synchronous and the $.getJSON() function is asynchronous. So i know i would have to pause the exectuion of the each() loop until the JSON File is parsed. How can i pause the loop? Or any other ideas solving this problem?
Thank you very much.
$("input:checkbox[name=check]:checked").each(function()
{
$.getJSON( $(this).val(), function( data ) {
//Do smth.
//Pause the each loop?
}).error(function(jqXhr, textStatus, error) {
alert("ERROR: " + textStatus + ", " + error);
});
});
alert("foo"); //<-- gets executed before all json files are parsed.
If you want to make the AJAX request synchronouse, pass async config as false.
$.ajax({
dataType: "json",
url: 'your URL',
async: false,
success: success
});
Documentation

how to make two dependent ajax requests on one buttonclick

I want insert two forms as two table rows in db using a button click event.I have used ajax request to insert in database and done for one form, while making another ajax request depending on first form it is not working
here is my java script using jquery.
var transportid = 2;
$.ajax({
url : '/TransportJob/create',
type : 'POST',
data : $('form[action="/TransportJob/Create"]').serialize(),
success : function sfn(data, textStatus, jqXHR) { // **success spelling mistake**
transportid = parseInt(data);
alert('inserted id :' + data);
$('#TransportJobId').val((transportid));
$.ajax({
url : '/TransportJobAddress/create',
type : 'POST',
//beforeSend: function myintserver(xhr){
// $('#addAddress').html('<div id="temp_load" style="text-align:center">please wait ...</div>');
//},
data : $('form[action="/TransportJobAddress/Create"]').serialize(),
success : function poste(data, textStatus, jqXHR) {
$('#addAddress').html(data);
},
error : function err(jqXHR, textStatus, errorThrown) {
alert('error at address :' + errorThrown);
}
});
},
error : function myfunction(jqXHR, textStatus, errorThrown) {
alert("error at transport :" + jqXHR.textStatus);
},
complete : function completefunc() {
alert('ajax completed all requests');
}
});
return false;
});
The first ajax sucess spelling problem make correction success then it will work
In your first ajax call, changesucess to success ?
I have modify your code first ajax request success portion spelling mistake.
sucess : function sfn(data, textStatus, jqXHR) {
Change to
success : function sfn(data, textStatus, jqXHR) {
Second error at end of request is
Remove extra code
return false;
});
and Put return false; after closing complete method.
e.g.
complete : function completefunc() {
alert('ajax completed all requests');
}
return false;
});

Trigger success handler is finished executing, with nested ajax requests

I have many nested ajax requests like below. I have a lot of things going on in the success function below, I need something like success that will trigger when success is complete. complete(jqXHR, textStatus) just seems to fire with success and I don't think .ajaxComplete() works.
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function (d1) {
//more nested ajax requests
},
});
SOLUTION:
A $.ajax() replacement plugin called $.fajax() (finished + ajax) has been created. Please check it out and let me know what you think. https://github.com/reggi/fajax (It's pretty well documented).
You could create a wrapper function for jQuery.ajax to make this a little cleaner:
var started = 0, done = 0;
var globalHandler = function(){
//do stuff when all success handlers are done
}
function handleAjax(args){
var _success = args.success || function(){};
args.success = function(jqXHR, textStatus){
_success(jqXHR, textStatus);
done++;
if(done >= started)
globalHandler();
}
var ajax = $.ajax(args);
started++;
return ajax;
}
usage
handleAjax({
url: 'api/periods.json',
dataType: 'json',
success: function (d1) {
//more nested ajax requests like this:
handleAjax({...});
}
});
This creates a closure so don't do any crazy memory-intensive stuff in there and you should be fine.
I'm not quite totally sure of what you're asking, so forgive me if I'm off-kilter, but I think you might want something like:
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function(d1){
//more nested ajax requests
},
}).done(function(msg){
alert("Every Ajax Call is Complete!");
});
You may want .queue() or .Defered
$("#el").queue("queue_name",function(){
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function(d1){
//more nested ajax requests
$("#el").dequeue("queue_name"); // tell queue success is complete
},
});
}).queue("queue_name",function(){
//do something you want when success is complete
})
$("#el").dequeue("queue_name"); // start to execute
or $.Deferred()
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function(d1){
var start = function(){
var dtd = $.Deferred();
//more nested ajax requests---------------
$.post("xxx",function(){
dtd.resolve(); // when success is complete
});
//----------------------------------------
return dtd.promise();
}
start.apply(this).pipe(function(){
//do something you want when success is complete
});
},
});

Categories

Resources