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>

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

I have tested and yes it works. dont know why it works, is just change var to const?
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: developer.mozilla.org/en-US/docs/Glossary/Scope
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: jsfiddle.net/76484/ok7vtu9y
@Hida: Do the above comments help to clarify this for you?
yes. it so help me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.