Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a parameter to FileReader onload event

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

like image 351
BeNdErR Avatar asked Jun 05 '13 10:06

BeNdErR


2 Answers

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.

like image 94
Graham Avatar answered Sep 21 '22 15:09

Graham


Use Blob API

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.

Use Fetch API

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.

like image 24
Janghou Avatar answered Sep 19 '22 15:09

Janghou