0

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.

  • Your final "what I'm trying to do" is pretty close actually. Just get those ajax request promises from the helper function calls into an array, then you can work with that (see the dupe) – Bergi Jun 19 '15 at 08:26
  • Thanks for your claarification. At first I was unable to apply taht soulution to my context, but I'll promptly take another look at it. – Dr. Gianluigi Zane Zanettini Jun 19 '15 at 08:30
  • Oh, and you forgot to declare `$respOk` and `$respErr` as local variables with `var` in your first snippet. – Bergi Jun 19 '15 at 08:32

0 Answers0