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