Reputation: 371
I'm fairly new to AJAX, but working on a project that requires an ajax call to validate a specific value, then make another ajax call if the first returns the expected value. I am trying to implement the .done/.fail model, but can't find a way to prevent both calls from happening simultaneously, rather than once the first call is done and successful.
The following code will call the ajaxCall function twice, but concurrently rather than consecutively. I have researched a ton of code, including Nested AJAX Calls, jQuery getting rid of nested ajax functions, and $.when.done callback isn't working, but none seem to fit my exact scenario, or maybe I just don't understand the code. Either way, I haven't been able to find a solution, and any help will be much appreciated!
var xReturn = ajaxCall("1");
xReturn.done(function(msg){
console.log("callback "+msg+" successful");
// if successful, place second call
if(parseInt(msg)==1)
xReturn = ajaxCall("2");
});
function ajaxCall(mop){
return $.ajax({
url: "getItem.php",
type: "POST",
data: {code: '<?php echo $code; ?> ', op:mop}
});
}
It seems like promises may be the way to go, but I can't wrap my head around how to use them in this scenario. Thanks in advance for any pointers in the right direction.
Update:
I ran through a battery of tests with different results. For my final test last night, I placed another console.log(msg);
directly after ajaxCall("2");
Each time the resulting msg was always "1", leading me to believe the calls were not happening properly. This result tells me that xReturn.done(function(msg)...
is only being called once, but I thought it would be called with each ajax call.
With this new information, I will perform additional testing tonight and report back.
Thanks
Upvotes: 1
Views: 9541
Reputation: 227230
You need to bind a .done()
method to each promise. xReturn.done()
binds a function to that promise.
When you do xReturn = ajaxCall("2");
, you are replacing xReturn
with a different object. This object does not have a .done()
method bound to it.
You need to bind .done()
to each promise, that doesn't happen automatically.
var xReturn = ajaxCall("1");
// This binds the callback to this *specific* promise
xReturn.done(ajaxDone);
function ajaxCall(mop){
return $.ajax({
url: "getItem.php",
type: "POST",
data: {code: '<?php echo $code; ?> ', op:mop}
});
}
function ajaxDone(msg){
console.log("callback "+msg+" successful");
// if successful, place second call
if(parseInt(msg)==1){
xReturn = ajaxCall("2");
// Bind a callback to this *new* object
xReturn.done(ajaxDone);
}
}
Upvotes: 1
Reputation: 32831
How about that:
var xReturn1 = ajaxCall("1"),
xReturn2 = ajaxCall("2");
$.when(xReturn1, xReturn2).done(function( a1, a2 ) {
var data1 = a1[0], data2 = a2[0];
console.log("Both done");
});
Upvotes: 0
Reputation: 1728
Try it like this.
ajaxCall("1");
function ajaxCall(mop){
$.post( "getItem.php", {code: '<?php echo $code; ?> ', op:mop})
.done(function( msg) {
console.log("callback "+msg+" successful");
if(parseInt(msg)==1)
ajaxCall("2");
});
}
And also you can use these with previous code
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "finished" );
Upvotes: 0
Reputation: 1037
There are multiple ways to go about this problem.
You could simply call the second ajax call from the success of the first. Something on the following lines
function ajaxCall(mop){
$.ajax({
url: "getItem.php",
type: "POST",
data: {code: '<?php echo $code; ?> ', op:mop}
}).done(function(msg) {
console.log("First call is done. Received data as ", msg);
if(parseInt(msg)==1) {
$.ajax({
//Repeat Options
}).done(function(newMsg)) {
console.log("We're done");
};
}
});
}
}
If you do want to use the .done/.fail model, you could try using $.when
.
Here is a working fiddle that does consecutive calls using the same function.
function ajaxCall(mop){
return $.ajax({
url: "/echo/json/",
type: "POST",
data: {
json: $.toJSON({data: mop}),
delay: Math.floor(Math.random()*4)
}
});
}
$.when(ajaxCall("1")).done(function(data) {
console.log("Done with first call. About to call second");
if(data /* and add whatever conditions you need to call the next function */) {
ajaxCall("2");
}
});
Upvotes: 0