0

I'm trying to send SMS to recipients from a object.
Does Jquery each loop wait for ajax success before continue?

I'd like my script to send one SMS and append a success text to DOM before continue with next recipient. When the each loop is done, i'd like to have a success message.

var i = 1;
var count =  Object.keys( recipients ).length;

//LOOP threw recipients
$.each(recipients, function(nr, name){
    //SEND SMS
    $.ajax({
        url: 'php/sms_send.php',
        method: 'POST',
        data: {nr: nr, name: name, text: text},
        success: function(result){
            //ECHO STATUS
            $('<span>'+result+'</span><br>').appendTo('#recipients');

        },
        error: function(err){
            //console.log(err);
        }
    }); //AJAX

     //LAST ROW?
    if(count === i){
        //DISABLE BTN
        $('#send_sms_btn').removeClass('disabled');
        $('#send_sms_btn').text('Skicka');
        //ECHO STATUS
        $('<span class="text-success">Klar!</span><br>').appendTo('#recipients');
    }
    else{
        i++;
    }
}); //EACH

The count does not work correct, and i wonder if the each is waiting for the ajax or if it just runs?

How can i make this workflow better?

Björn C
  • 3,860
  • 10
  • 46
  • 85
  • 1
    Possible duplicate of [each wait until finish $.ajax , and then continue](https://stackoverflow.com/questions/8657401/each-wait-until-finish-ajax-and-then-continue) – Ayaz Ali Shah Jan 28 '18 at 09:30
  • To answer your first (and repeated second) question: no, the loop does not wait for the AJAX call to return an response. That's what the first A in AJAX stands for: asynchronous. – rolfv1 Jan 28 '18 at 09:30
  • AJAX does not wait, it is async. To do one at a time you'll need to use continuations and keep track of where you are in the collection rather than using a loop. – Richard Jan 28 '18 at 09:30

1 Answers1

0

You don't need a messy count.

Just aggregate the jqXHR promises returned by $.ajax() and do whatever is necessary when they have all resolved.

// map recipients to promises
var promises = $.map(recipients, function(name, nr) {
    // return a jqXHR promise
    return $.ajax({
        'url': 'php/sms_send.php',
        'method': 'POST',
        'data': { 'nr': nr, 'name': name, 'text': text }
    }).then(function(result) {
        $('<span>' + result + '</span><br/>').appendTo('#recipients');
    });
});

// now aggregate the promises
$.when.apply($, promises).then(function() {
    // arrive here when all promises have resolved
    $('#send_sms_btn').removeClass('disabled').text('Skicka');
    $('<span class="text-success">Klar!</span><br>').appendTo('#recipients');
});
Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
  • 1
    Cool. I'm not so familiar with map, so i will read up on it. Thank you. It seems to work correctly :D – Björn C Jan 28 '18 at 14:14