I need to read some csv files, given by the user. Files are passed to the page/script using a drag and drop div, that handles the file drop as follows:
function handleFileDrop(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files; // FileList object.
    ...
}
I need to parse each file with a csv library that converts it into an array, but I also need to keep track of the file name I'm currently parsing. Here's the code I use to parse each file:
for(var x = 0; x < files.length; x++){
    var currFile = files[x];
    var fileName = currFile.name;
    var reader = new FileReader();
    reader.onload = (function(theFile){
        return function(e){
            var csvArr = CSV.csvToArray( e.target.result, ";", true );
            console.log(csvArr); 
        };
    })(currFile);   
    reader.readAsText(currFile);
}
Until this, everything works great. What I need is to also pass the filename to the reader.onload event, eg:
reader.onload = (function(theFile){
    return function(e){
       ***** I need to have fileName value HERE *****
    };
})(currFile); 
Is possible? How can I do this? Thanks in advance for any help, best regards
Try the following:
var reader = new FileReader(); reader.onload = (function(theFile){     var fileName = theFile.name;     return function(e){         console.log(fileName);         console.log(e.target.result);     }; })(currFile);    reader.readAsText(currFile);   Here, you're creating a new fileName variable each time a file is passed to the outer method. You're then creating a function which has access that variable (due to the closure) and returning it.
Using the new File / Blob API it can be done much easier.
Your second code block - also solving your problem - could be rewritten as:
for (let file of files){  (new Blob([file])).text().then(x=>console.log(file.name,x)); }   The Blob API uses Promises instead of Events like the Filereader API, so much less troubles with closures. Also the Arrow function (x=>) and iterator for of, make the code much more concise.
Check support.
Also using the Fetch API Response Object it can be done more easy.
for (let file of files){  (new Response(file)).text().then(x=>console.log(file.name,x)); }   Note of the missing Array [] in the constructor.
Also check support.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With