1

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!

  • 3
    Well that makes perfect sense, since `$.ajax(..)` indeed just simply sends a request, the `success: ...` is a *callback* that is done after the request was succesfull. Here it is definitely possible that the values will be appended in a different order than how you submitted it. – Willem Van Onsem Sep 07 '19 at 07:48
  • look for snippets like sequential ajax, or better have a master mailer where you send all data and the BE then loops and process, that way you will have one single http request, saves bandwidth and too much to and fro communication between client server – joyBlanks Sep 07 '19 at 07:56

3 Answers3

1

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 .

Pushprajsinh Chudasama
  • 7,772
  • 4
  • 20
  • 43
1

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

sigmus
  • 2,987
  • 3
  • 23
  • 31
1

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()?

Deepak
  • 125
  • 2
  • 12