code killer
code killer

Reputation: 9

How to Send Single request using ajax inside a loop

I create a simple mailer for our updates into client emails, But how can I send the data one by one and process each data on server side

html:


<p class="response"></p>

<form id="send_updates">
    {% csrf_token %}
    <textarea name="mail-list" class="mails" id="mails"></textarea>
    <button type="submit"> start sends </button>
</form>

javascript:

let mails = $('#mails').val().split('\n');
for(let i = 0; i <= cc.length; i++){
    $.ajax({
        cache: false,
        type: 'post',
        url: "{% url 'send_mail' %}",
        data: {'email': mails[i]},
        async: true,
        beforeSend:function(xhr, settings){
            xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
        };
        success: function(data){
            if (data.success) == true{
                $('.response').append(mails[i] + ' sent!')
            }else{
                $('.response').append(mails[i] + ' not sent!')
            };
        }
    });

BUT! It Sends All Request without waiting if it Success or Not

EDIT:

We Want to Monitor One By One If That Email is Send Successfully or Not!

Upvotes: 1

Views: 106

Answers (3)

Deepak
Deepak

Reputation: 125

Try setting

    async: false,

as shown below:

    let mails = $('#mails').val().split('\n');
    for(let i = 0; i <= cc.length; i++){
    $.ajax({
      cache: false,
      type: 'post',
      url: "{% url 'send_mail' %}",
      data: {'email': mails[i]},
      async: false,
      beforeSend:function(xhr, settings){
        xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
      };
      success: function(data){
        if (data.success) == true{
            $('.response').append(mails[i] + ' sent!')
        }else{
            $('.response').append(mails[i] + ' not sent!')
        };
      }
     });

Refer What does "async: false" do in jQuery.ajax()?

Upvotes: 1

sigmus
sigmus

Reputation: 3237

If you need to update the UI as they happen:

function fetchNextMail(mails) {
  const nextMail = mails.shift();
  $.ajax({
    type: "get",
    url:
      "https://jsonplaceholder.typicode.com/todos/1"
  }).then(res => {
    console.log(Object.keys(res));
    console.log(mails.length);
    mails.length && fetchNextMail(mails);
  });
}

fetchNextMail(["x", "y", "z"]);

If you can wait for all of them to finish to update the UI, you can use Promise.all:

Promise.all(
  ["x", "y", "z"].map(mail => {
    return $.ajax({
      type: "get",
      url: "https://jsonplaceholder.typicode.com/todos/1"
    });
  })
).then(results => {
  // results[0], results[1] and results[2]
  console.log(results.length);
});

A working example can be found here: https://codesandbox.io/s/jquery-playground-i2vb4

Upvotes: 1

Pushprajsinh Chudasama
Pushprajsinh Chudasama

Reputation: 7949

You can use the async/await .

function getData(ajaxurl , mail) { 
        return $.ajax({
            cache: false,
            type: 'post',
            url: "{% url 'send_mail' %}" /*instead `ajaxurl`*/,
            data: {'email': mail},
            beforeSend:function(xhr, settings){
                xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
            },
            success: function(data){
                if (data.success == true){
                    $('.response').append(mails[i] + ' sent!');
                }else{
                    $('.response').append(mails[i] + ' not sent!')
                }
            }
        });
    };

    async function test(mail){
        try {
            const res = await getData('https://api.icndb.com/jokes/random' , mail);
            console.log(res);
        } catch(err) {
            console.log(err);
        }
    }



    var mails = $('#mails').val().split('\n');
    for(let i = 0; i <= cc.length; i++){
        var mail = mails[i];
        test(mail);
    }

Try out this method . Here the test() function is async and will await for getData() function to complete everytime . Through this , you will achieve your goal .

Upvotes: 1

Related Questions