Jquery ajax call within an each loop
Asked Answered
C

5

12

I'm having a problem when using the jquery .each() and .ajax() functions together. I'm using .each() to loop through 5 elements and am performing the .ajax() call for each one. My problem is that I only want the loop to continue when a response has been received from each ajax request. Currently, all 5 elements are being looped, 5 ajax requests being made, then 5 responses being returned.

Hers's a simple example:

$(".element").each(function() {
    var id= $(this).find(('txtId').val();
    $.ajax({
       type: "POST",
       url: "/Handlers/Handler.ashx",
       data: "ID=" + id,
       success: function(xml){

         // I would like the each() loop to pause until this is hit, 
         // and some additional logic can be performed. 

       }
     });

});

Cheers.

Cristiecristin answered 13/7, 2010 at 13:22 Comment(0)
C
11

You could use the async option for this to make each request synchronous (= halt script execution until each request is finished):

async By default, all requests are sent asynchronous (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.

but, as the docs already say, this is highly discouraged, as it could freeze the browser if a request hangs or times out.

It would be better to change the architecture of your code in a way that can work with the classical callback functions if at all possible.

Condyloid answered 13/7, 2010 at 13:24 Comment(1)
Cheers for the help, I've gone with your suggestion and changed the structure of my code, I've removed the loop and use recursion instead. Works ok now.Cristiecristin
B
4

Pekka has the correct answer. You just need to edit your script as below.

$(".element").each(function() {
    var id= $(this).find(('txtId').val();
    $.ajax({
       type: "POST",
       async: false,
       url: "/Handlers/Handler.ashx",
       data: "ID=" + id,
       success: function(xml){

       }
     });

});
Briefcase answered 13/7, 2010 at 13:34 Comment(2)
I have tried this, I can see why it is highly discouraged. Seemingly setting this to false causes my browser to freeze until all responses have been received and the loop has finished.Cristiecristin
I am not sure what you were expecting to occur. If you want the script to pause and wait for the response then it will do exactly that pause and wait. Maybe you should explain what it is exactly that you are looking to accomplish as there may be a better way. There is probably a better way to achieve the end results you desire with a different algorithm.Briefcase
Q
0

i'm happy to say there's a way... but it's a bit nasty.

If you are sure the request has to give something back, then you can remove the "tryIteration" part.

$(document).ready(function() {

        loop(".buttonsPromotion", 0);

});

function loop(elements, tryIteration) {
//HOW MANY TRIES UNTIL WE STOP CHECKING
if(tryIteration<7){

    $(elements).each(function() {            
        var actuel = $(this);
        $.ajax({
           url: "write your link here",
           data: {},
           dataType: 'json',
           async: true,
           success: function(data){
               //HERE WE KNOW THE AJAX REQUEST WENT OK
               actuel.addClass('AjaxOK');    
           },
           error:function(thrownError){
                console.log(thrownError);
                //WE MAKE ANOTHER EACH ON ALL ELEMENT THAT WENT BAD
                var elemToRetry = actuel.not('AjaxOK');
                loop(elemToRetry, ++tryIteration);
            }
         });

    });
}
}
Quiteris answered 5/7, 2011 at 11:6 Comment(1)
Why not just breaking out of the each loop when the first ajax request returns success?Liveried
C
0

You can use the jquery deffered and promise function to check the async call is success or not. http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

Custom answered 8/10, 2012 at 13:57 Comment(0)
M
0

Although it's late, i used a work around for this I created a function to handle the ajax request by passing the element

function ajax_request(element){
    var id = element.find('.txtId').val();
    console.log(id);
    $.ajax({
        type: "POST",
        url: "/Handlers/Handler.ashx",
        data: "ID=" + id,
        success: function(xml){
            console.log(xml);
        }
     });
}

$(".element").each(function() {
    // run the ajax function for current element
    ajax_request($(this));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="element">
    <input class="txtId" value="textid1"/>
</div>
<div class="element">
    <input class="txtId" value="textid2"/>
</div>
<div class="element">
    <input class="txtId" value="textid3"/>
</div>

Hope it helps anyone doing something similar

Meperidine answered 25/3, 2021 at 20:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.