1

I am uploading multiple files using XMLHttpRequest at the same time. I want each file to have its own progress indicator. So, when I get array of files for upload, I initiate upload for each of them inside a for cycle like

for(var i=0; i<files.length; i++)                    
{
  // Create transfer object
  var xhr = new XMLHttpRequest();

  // Attach progress event handler
  xhr.addEventListener('progress', function(e) { showProgress .... });

 ....
}

The issue is, how to pass correct "i" value to the progress callback function. In case I use "i" like this:

  xhr.addEventListener('progress', function(e) { console.log(i); });

I always get the latest "i" value. In case define it like this:

  xhr.addEventListener('progress', (function(i,e) { console.log(i); })(i));

I get correct I, but I never get the event object "e", so I don't get actual progress. What is correct way of defining it?

user3523426
  • 836
  • 3
  • 11
  • 26
  • 1
    Create one function with the for-loop content expecting the i-value as parameter. Then in your for-loop call the function. It should work because i-value will be passed without reference. – Washington Guedes Jun 28 '16 at 13:54
  • 1
    Use let or use it like `xhr.addEventListener('progress', (function(i) { return function(e) {console.log(i);} })(i));` – Redu Jun 28 '16 at 14:06

1 Answers1

1

Use xhr.upload.progress instead of xhr.progress.

Create an IIFE, pass i to IIFE, create new progress element having className "progress-" with i concatenated, update current progress element .value to e.loaded within upload progress event. See also Upload multiple image using AJAX, PHP and jQuery

for(var i=0; i<files.length; i++) {
  // Create transfer object
  (function(curr) {
    // `i` : `curr`
    var xhr = new XMLHttpRequest();
    var progress = document.createElement("progress");
    progress.setAttribute("max", files[curr].size);
    document.body.appendChild(progress);
    progress.className = "progress-" + curr;
    // Attach progress event handler
    xhr.upload.addEventListener("progress", function(e) {
      // update current `progress` `value`
      document.querySelector(".progress-" + curr).value = e.loaded;
    });
    xhr.open("POST", "/path/to/server/");
    xhr.send(new FormData(files[curr]));
  }(i)); // pass `i` to IIFE
}

jsfiddle https://jsfiddle.net/ytedpcro/1/

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177