jQuery Ajax Race Condition?

ajax, javascript, jquery

Solution

You're already using synchronous AJAX (a really bad idea for your user experience), so that's not the problem. The problem is that you need to cancel the default action in the "submit" handler:

$(".submitForm").click(function(e){
   var submittable = validatePrices();
   e.preventDefault(); // this line
   if (submittable) {
     $("#myForm").submit();
   }
 });

Using a synchronous HTTP request back to your server for each separate field is going to make your site terribly slow. You're going to have to check the parameters at the server again when you submit the form anyway, so it'd be much better to just check then and return an error.

edit — now that the situation is clearer, I think that the way to proceed is to stop doing the AJAX validation checks completely. Why? Well, even if you perform those tests, you still need to make essentially the same validity tests when the form is actually submitted. You can't rely on the JavaScript validation code actually running, as in any other form validation scenario. If you're doing the validation at form submission time anyway, it'll save on a bunch of HTTP requests to just do it all at the same time.

Problem

I have the below JavaScript code that iterates through a list of textfields on a page. It takes the text in the textfield as a price, sends it to the server via an AJAX GET, and gets the parsed double back from the server. If any of the returned prices are less than an existing price, the form shouldn't submit. The problem is that the form is submitting before all the AJAX requests are finished because of the non-blocking immediate response nature of the Ajax calls. I need to set up a wait() function (or a callback when all the Ajax methods are complete) but don't know how to do that with jQuery. Any suggestions? ``` // .submitForm is a simple button type="button", not type="submit" $(".submitForm").click(function(e){ var submittable = validatePrices(); if (submittable) { $("#myForm").submit(); } }); function validatePrices() { var submittable = true; $(".productPrice").each(function(){ var $el = $(this); $.ajax({ type: "POST", url: "/get_price.jsp", async: false, dataType: "html", data: "price=" + $el.val(), success: function(data) { var price = new Number(data.split("|")[1]); var minPrice = new Number($el.data("min-price")); if (price < minPrice) { $el.addClass("error"); $(".dynamicMessage").show().addClass("error").append("<p>ERROR</p>"); submittable = false; } } }); return submittable; }); } ```

Original source