0

I want to increment the value of a variable ii, but its value does not change. If I move ii++; before the alert function call, it increases but the value set to #spanstatus is always 0. How do I increment the value of ii, and still access it before my $.ajax call?

<html> 
      <span id="spanstatus"></span><br>

<script src="../js/jquery-1.12.4.min.js"></script>
<script>
var data = new FormData();
data.append('test', 'a');
data.append('test1', 'b');
data.append('test2', 'c');

function upload() {
        $('#spanstatus').html('');
        var ii=0;
        for(var [name, value] of data) {
            $('#spanstatus').append('<i>Uploading <b>"'+name+'"</b></i>...<span id="spanupload_'+ii+'">'+ii+'</span><br>');
                $.ajax({
                    type:'POST',
                    method: 'POST',
                    timeout:2000,
                    url:'upload.php?val='+value,
                    dataType: "json",
                    data:  value,
                    contentType: false,
                    cache: false,
                    processData:false,
                    // async: false,
                    success:function(response){
                            $('#spanupload_'+ii).html(ii+' OK');
                            alert(ii+'ok='+name);
                            ii++;
                    }
                });
        }
}

$(document).ready(function(){
    upload();
});

</script>
 </body> 
</html>
76484
  • 8,498
  • 3
  • 19
  • 30
Hida
  • 154
  • 10

1 Answers1

1

The success handler does not execute until the the response is received, which happens sometime later, as this is an asynchronous handler. This means the value of ii will not have changed when you make each call to $('#spanstatus').append.

You could move the incrementing of ii so that it happens before the $('#spanstatus').append, but this introduces a new problem. In the success handler, ii will have been incremented once for each object in data, so it will always have the same value - in this case, 3 - when you call $('#spanupload_'+ii).html(ii+' OK').

In order to keep a reference to each iteration within the for of loop, you must create a local, block-scoped variable with the value of ii at that iteration. You would need to do the same for name. The code would look like:

var data = new FormData();
data.append('test', 'a');
data.append('test1', 'b');
data.append('test2', 'c');

function upload() {
  $('#spanstatus').html('');
  var ii = 0;
  for (var [name, value] of data) {
    ii += 1;
    const nextii = ii;
    const nextName = name;

    $('#spanstatus').append('<i>Uploading <b>"' + nextName + '"</b></i>...<span id="spanupload_' + nextii + '">' + nextii + '</span><br>');
    $.ajax({
      type: 'POST',
      method: 'POST',
      timeout: 2000,
      url: 'upload.php?val=' + value,
      dataType: "json",
      data: value,
      contentType: false,
      cache: false,
      processData: false,
      // async: false,
      success: function(response) {
        $('#spanupload_' + nextii).html(nextii + ' OK');
        alert(nextii + 'ok=' + nextName);
      }
    });
  }
}

$(document).ready(function() {
  upload();
});

I have created a fiddle for reference.

76484
  • 8,498
  • 3
  • 19
  • 30
  • I have tested and yes it works. dont know why it works, is just change var to const? – Hida May 05 '23 at 02:53
  • `const` is part of it. `const` is block-scoped, which means we are creating a new variable on each iteration through the `for...of` loop which has a life only within its iteration. In contrast, `var`, is scoped to the function. This means there is a single variable used across each iteration of the `for...of` loop, so, by the time the `success` handler fires, the value of the variable declared with `var` will contain the last value assigned to it. Here is some more info on scopes: https://developer.mozilla.org/en-US/docs/Glossary/Scope – 76484 May 05 '23 at 03:18
  • You could also use `const` within the `for...of` loop so that you would not need to declare a new variable to hold the name value: `for (const [name, value] of data) {`. I have a forked version of the fiddle with this approach: https://jsfiddle.net/76484/ok7vtu9y/ – 76484 May 05 '23 at 03:21
  • @Hida: Do the above comments help to clarify this for you? – 76484 May 05 '23 at 13:42
  • 1
    yes. it so help me – Hida May 06 '23 at 07:08