1

I am doing a simple file text upload using FileReader.

var filesInput = document.getElementById("txtImport");

for (var i = 0; i < filesInput.files.length; i++) {
    current = filesInput.files[i];

    var reader = new FileReader();
    reader.onload = function(file) {
        return function(e) {
            console.log('e', e) // not logging
        }
    }(current)
}

Upon reading FileReader onload with result and parameter, I need to use closure so as to not lose the scope inside the loop. When I click the button to trigger the upload, why is the log not coming up? Why isn't the function firing?

patrickhuang94
  • 2,085
  • 5
  • 36
  • 58

1 Answers1

5

You need to call one of the readAs___ methods of the FileReader:

https://developer.mozilla.org/en-US/docs/Web/API/FileReader

If you're reading multiple files parallel, you need a separate reader for each.

Also, the parameter the event handler receives is an event object, not the contents of the file. Those will be in reader.result.

for (var i = 0; i < filesInput.files.length; i++) {
    let reader = new FileReader();
    reader.onload = function(event) {
        console.log(reader.result);
    }
    reader.readAsText(filesInput.files[i]);
}
Máté Safranka
  • 4,081
  • 1
  • 10
  • 22
  • That worked but can you explain why I didn't need to use closure to not lose the scope? – patrickhuang94 Apr 01 '18 at 19:53
  • Functions have access to all variables in the scope where they are defined. Thus, the handler function can see the `FileReader` because they were defined in the same scope. Each iteration of the loop creates a new `FileReader` and a new function, so each function sees a different reader. Does that make sense? – Máté Safranka Apr 01 '18 at 19:56
  • MDN also has a more detailed explanation here, that'll probably do you more good: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures – Máté Safranka Apr 01 '18 at 19:57
  • Awesome, thanks for the link and explanation! Going off of this, I'm trying to assign `reader.result` to a variable inside the onload function - however, logging the variable outside of the onload returns undefined. What's going on there? – patrickhuang94 Apr 01 '18 at 19:59
  • @patrickhuang94 Sorry, just noticed your edit. Did you do something like this: `reader.onload = function(event) { var fileContents = reader.result; }` ? The emphasis here is that the `fileContents` variable is declared inside the `onload` function. Local variables are only visible inside the function where they're declared. You need to store the results in a broader scope if you want other functions to access it. – Máté Safranka Apr 03 '18 at 10:55