byCoder
byCoder

Reputation: 9184

Parse multiple files with javascript: the same file in for-loop

I have such code:

    function processFiles(e) {

      var filesInput = $('#files').prop('files');
      var i, f;

      for (i = 0, f = filesInput[i]; i != filesInput.length; ++i) {

        var name = f.name;
        console.log(name); //why here is the same file, even if i select in file input 2 different?

        var reader = new FileReader();

        reader.onload = function(e) {
          var myFile = e.target.result;
          console.log(myFile);  //why here is the same file, even if i select in file input 2 different?
        };
        reader.readAsBinaryString(f);
      }
    }

    $('#sbmt').click(function(e) {
      processFiles();
    });

but when i try to parse multiple files, i got the same file in for loop & .onload callback

what i do wrong?

Upvotes: 1

Views: 741

Answers (2)

Endless
Endless

Reputation: 37806

My 2 cents:
Took a crack at using Response (part of the new fetch api) to get the buffer with help of es6 and Promises

function processFiles(e) {
  let files = $('#files')[0].files
  let buffers = [...files].map(file => new Response(file).arraybuffer())

  Promise.all(buffers).then(buffers => {
    // concatinate(buffers)
  })
}

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074238

why here is the same file, even if i select in file input 2 different?

Because nothing updates f in the for loop. You've set f in the initialization expression, but you don't update it in the update expression.

If you want to use the for to control f, be sure you update f:

for (i = 0, f = filesInput[i]; i != filesInput.length; ++i, f = filesInput[i]) {
// -------------------------------------------------------^^^^^^^^^^^^^^^^^^^

...but at that point, you're duplicating code; instead, I'd just move the sssignment into the loop body:

for (i = 0; i != filesInput.length; ++i) {
    f = filesInput[i]

...or more likely I'd probably use forEach:

function processFiles(e) {
    Array.from($('#files').prop('files')).forEach(function(f) {
        var name = f.name;

        var reader = new FileReader();

        reader.onload = function(e) {
            var myFile = e.target.result;
            console.log(myFile);
        };
        reader.readAsBinaryString(f);
    });
}

(Note that that uses Array.from from ES2015; you'll need a polyfill to use that in the wild for now...)

Upvotes: 1

Related Questions