Count rows with javascript

1

I have a script where I get all the emails of a textarea , sending them via Ajax to another page, using the split to separate the lines. However, if I have 10 emails to send the newslast every 1s it runs and sends line by line to my Ajax. So, how can I count the lines that have already been sent?

  

Email Sent: 0

     

With each line being sent I would like this counter   increase by 1 by one by one until you reach the end.

HTML

    <div id="env">

            <form>

                <textarea id="email" placeholder="[email protected]"></textarea>
                <input type="button" id="execute" class="btn btn-success" value="Executar NewLast">

            </form>

            <hr>

            <div class="alert alert-dark" role="alert">
              E-Mails Enviados: 01
            </div>
            <div class="alert alert-success" role="alert">
              Enviado com sucesso para: [email protected]
            </div>

        </div><!--env-->


JS


    $("#execute").click(function(){

    var email = $("#email").val();
    var index = 0;
    splitemail = email.split("\n");

    splitemail.forEach(function(value){


        setTimeout(function(){

            $.ajax({
            url:'ajax.php',
            method:'GET',
            data: {
                email: value,
            }

            }).done(function(retorno){
                $("#ren").html(retorno);

            })

        }, 1000 * index)

        index = index + 1;
    })



}); 
    
asked by anonymous 27.12.2017 / 09:29

2 answers

0

I'll try to give you an explanation so you understand what you did, by your answers I believe you wrote but did not understand.

The setTimeout will run the code contained in your function, which is a callback, only after the time set in the second parameter of that function in the case below is 3000 milliseconds which corresponds to 3 seconds. / p>
setTimeout(function(){ alert("Hello"); }, 3000);

So if I set the time as below:

$("#execute").click(function(){
    var email = $("#email").val();
    var index = 0;
    splitemail = email.split("\n");
    splitemail.forEach(function(value){
        setTimeout(function(){
            $.ajax({
                    url:'ajax.php',
                    method:'GET',
                    data: { email: value }
        }).done(function(retorno){
            $("#ren").html(retorno);
        })
    }, 1000 * index);
    index = index + 1;
});

is saying that it is to send the request every 1000 milliseconds X index (1000 X index). But who is index, index is a variable contained in your local scope of the onclick event that is triggered when there is a click on the button on your form defined by the id #execute . The index variable is incremented by +1 to each interaction of your foreach, which in the case is a loop defined by the amount of items contained in your splitemail array . Therefore, as the ajax request will be invoked depending on the amount of line breaks contained in your textarea each foreach interaction will multiply 1000 milliseconds per index, in the first loop interaction its time will be 1000x0 once index is started with zero, in the second loop interaction setTimeout will have the time parameter of 1000 * 1 = 1 second (because index is 1), and the third time will have the parameter 1000 * 2 = 2 seconds because index will be two and so on. So porting will not be 1 second as I said in your question and reply to my comment. With each new interaction the shipping time gradually goes up because it is multiplying index times 1 second.

If setTimeout will wait for the time set in the parameter would just suffice.

setTimeout(function(){
    $.ajax({
            url:'ajax.php',
            method:'GET',
            data: { email: value }
    }).done(function(retorno){
       $("#ren").html(retorno);
    })
}, 1000); 

Your question refers to how you could count the number of items already shipped. In your routine you set and variable index, with each increment of the loop the variable is incremented by 1. So at the end of the foreach interaction of your array the total value of index will be the amount of items in your array splitemail . And if you want to know the total amount is as I said in comment after the split of the value contained in your textarea just use the lenght in the array to get the total amount of messages contained in the listing.

/* Devolve a quantidade total de mensagens contidas no campo textarea
após transforma-las em uma array (uma lista) explodindo a string com o \n 
(quebra de linha) utilizando a função split */

var qtd_linhas = splitemail.length;

I've set up this example by printing the time value in setTimeout to understand it better.

Routine Shipping Test

Insert text-wrapping emails in textarea, and then click RUN :

This example would be correct, with the amount of emails sent displaying in your div. click to test

$("#execute").click(function(){
     var email    = $("#email").val();
     var index    = 1;
     splitemail   = email.split("\n");  
     splitemail.forEach(function(value){ 
         alert("O tempo de espera é : "+(1000 * index));
         setTimeout(function(){ 
             alert(value); 
             $('#cnt_enviados').text("E-Mails Enviados: "+index); 
             index = index + 1;
         }, 1000);
     });
});
    
27.12.2017 / 18:24
0

I see the following issues in your code:

1. forEach

The forEach is not a good one, because it will give a loop without expecting anything, that is, it will call the array elements immediately without queuing, executing everything in it in a continuous and direct way.

2. SetTimeout

The way you put it, will call Ajax every 1 second, but will not respect the processing and will send another request after 1 second, and so on, and can create a bottleneck in the processing of your server.

Suggestion

Create a function that will send requests, and each time Ajax processing is terminated, you check if there is still an email in the array queue to be sent and call the same function again. Each time Ajax is processed, you increment the variable index and throw the value in the <span> that I created as a counter. If I explain each change in the code it will give a huge text. You can see directly what has been improved and implemented in the code:

HTML:

<div id="env">
   <form>
      <textarea id="email" placeholder="[email protected]"></textarea>
      <input type="button" id="execute" onclick="envia()" class="btn btn-success" value="Executar NewLast">
   </form>
   <hr>
   <div class="alert alert-dark" role="alert">
     E-Mails Enviados: <span id="conta">0</span>
   </div>
   <div id="ren" class="alert alert-success" role="alert">
   </div>
</div><!--env-->

JavaScript:

var index = 0;
function envia(){
   var email = $("#email").val().trim();
   splitemail = email.split("\n");

   if(index < splitemail.length){

      $.ajax({
         url:'ajax.php',
         method:'GET',
         data: {
           email: splitemail[index],
         }
      }).done(function(retorno){
         index++;
         $("#ren").append('<br />'+retorno);
         $("#conta").html(index);
         setTimeout("envia()", 1000);
      });
   }
}

In ajax.php, it should return something like this:

<?php
$email = $_GET['email'];
echo 'Enviado com sucesso para: '.$email;
?>
    
28.12.2017 / 01:40