Let me explain my code a little bit (Excuse me if somethings wrong, I've just written this example from scratch, it is very close to what I currently have).
HTML:
<form id="form">
<!-- Friend 1 -->
Name 1: <input type="text" name="friendName1" id="friendName1" class="friendName" value=""><br />
Email 1: <input type="text" name="friendEmail1" id="friendEmail1" value=""><br /><br />
<!-- Friend 2 -->
Name 2:<input type="text" name="friendName2" id="friendName2" class="friendName" value=""><br />
Email 2:<input type="text" name="friendEmail2" id="friendEmail2" value=""><br /><br />
<!-- Friend 3 -->
Name 3:<input type="text" name="friendName3" id="friendName3" class="friendName" value=""><br />
Email 3:<input type="text" name="friendEmail3" id="friendEmail3" value=""><br /><br />
<!-- Friend 4 -->
Name 4:<input type="text" name="friendName4" id="friendName4" class="friendName" value=""><br />
Email 4:<input type="text" name="friendEmail4" id="friendEmail4" value=""><br /><br />
<!-- Submit -->
<input name="submit" type="submit" value="Submit">
</form>
JS:
$("#form").submit(function(){
$(".friendName[value!='']").each(function(){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
if($("#"+idEmail+"[value!='']").length > 0){
var name = $(this).val();
var email = $("#"+idEmail).val();
// Submit the ajax request
$.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
});
}
});
// Redirect the user to the thank you page
setTimeout( function() { window.location= '/thanks'; }, 2000 );
});
JSFiddle (redirect removed and ajax call replaced with console log for fiddle)
http://jsfiddle.net/cM5PX/
The HTML is a simple form, with friend name and friend email input fields.
The JS has an each function, which if the name and associated email have values, it runs an ajax call.
I need a way for these ajax calls to run (there could be 1 loop, there could be 15) and then after they have all finished, redirect to a new page.
The current way I'm doing it is horrible, as all of the ajax calls do not finish running before the page redirects.
What can I do to make this better? It needs to be fool proof and ONLY redirect once all of the ajax calls have finished (success or error, it doesn't matter - it just needs to redirect once its finished).
I have tried using async: false
but it doesn't seem to make a difference.
I've thought about putting a counter in the each function and a counter in the ajax success function and if they both match, then do the redirect, but I am looking for some more experienced guidance.
}); If isLoading is false, the AJAX call starts, and we immediately change its value to true. Once the AJAX response is received, we turn the value of that variable back to false, so that we can stop ignoring new clicks.
jQuery ajaxStop() Method The ajaxStop() method specifies a function to run when ALL AJAX requests have completed. When an AJAX request completes, jQuery checks if there are any more AJAX requests. The function specified with the ajaxStop() method will run if no other requests are pending.
If you don't want the $. ajax() function to return immediately, set the async option to false : $(". my_link").
There is a requirement to make multiple AJAX calls parallelly to fetch the required data and each successive call depends on the data fetched in its prior call. Since AJAX is asynchronous, one cannot control the order of the calls to be executed.
Use deferred objects:
$("#form").submit(function(e){
e.preventDefault();
var calls = [];
$(".friendName[value!='']").each(function(){
// Submit the ajax request
calls.push($.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
}));
});
$.when.apply($, calls).then(function() {
window.location= '/thanks';
});
});
Ok, this is fairly easy since you're using jQuery. jQuery comes with an integrated promise maker which also is wired up with jQuery's Ajax calls. What does that mean? Well, we can easily go like this:
var requests = [ ];
// ...
// Submit the ajax request
requests.push($.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
}));
// at this point we filled our array with jXHR objects which also inherit the promise API
$.when.apply( null, requests ).done(function() {
document.location.href = '/thanks';
});
Note: The above code will only fire, if all requests completed successfully. If you need to handle the case if one ore more requested failed, use .then()
or .fail()
instead of .done()
, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With