I'm handling the visibile/non-visible status of a product (let's say it's a "complete car") in a jQuery webapp.
Overview
When the user chooses to make a product visible/non-visible, I must list all the the subproducts of the main product (for "car", those may be "wheels", "brakes", ...).
If the user chooses any subproducts, I must do a single Ajax request for each subproduct and show the response next to it.
If all the subproducts requests report an "OK" status, I must run one last Ajax request and act on the main product. If one of the subproduct requests fails/returns an error, I must stop there and don't run the last request on the main product.
I don't know how many subproducts there are. Could be 0, could be 100.
I must follow this flow and I must use one request for each subproduct and one final for the main product.
First non-working idea
Let's focus first on the all-subproducts. This is the fragment I'm using to loop over the checked subproducts.
$ads.each(function () {
if($check.prop("checked")) {
$respOk = $(this).find('img.response-ok'); //this point to the img with "response OK"
$respErr = $(this).find('img.response-error');//this point to the img with "response failed"
$.ajax({
type: "POST",
url: "<action_url>",
data: $form.serializeArray(),
success: function(msg) {
if (msg.error == false) {
$respOk.slideDown(); //this lags behind and shows the wrong one!
} else {
$respErr.slideDown(); //this lags behind and shows the wrong one!
}
},
error: function(msg) {
$respErr.slideDown();
},
complete: function(msg) {
$respLoad.stop().slideUp(); //this lags behind and shows the wrong one!
}
});
}//end ad checked
});//end ads loop
The problem is: being the Ajax request non-blocking, the loop loops immediately and overwrites the $respOk and $respErr variables => when the complete/error fires, it evaluates the currently assigned value of them and displays the image always on the last item of the list.
Second non-working idea
Use async: false in all the ajax requests. This works, but stalls the main browser thread in unacceptable ways.
Third non-working idea
I moved the ajax request in an helper function:
$ads.each(function () {
if($check.prop("checked")) {
helperFunctionWithAjaxRequest(<params..>)
});
}//end ad checked
});//end ads loop
This actually solves the problem of the first implementation (each $respXX reference points to the right subproduct) and the response are correctly shown next to its subproduct.
But now I've a different problem: as the previous one, the whole loop loops immediately and I've no way of wait for all the requests to complete and decide if they went right (so fire the last request on the main product) or not (so stop there).
What I'm trying to do
I'm basically trying to do something like this:
$.when(
$ads.each(function () {
if($check.prop("checked")) {
helperFunctionWithAjaxRequest(<params..>)
});
}//end ad checked
});//end ads loop
).then(function() {
//run my code to check if everthing went right (I can already do that)
//if so, run the Ajax request on the main product (I can already do that)
});
But I really cannot understand the syntax to use (or if the when/then is the right way to do this).
Any help? I'd really appreciate suggestions on the "What I'm trying to do" codepath.