I am using the following to upload multiple files in Salesforce custom lightning component.
http://sfdcmonkey.com/2017/09/25/file-upload-lightning-component
I my component, I have the following code
<lightning:input aura:id="fileId" onchange="{!c.handleUploadFinished}" type="file" name="file" label="Upload Attachment" multiple="true"/>
In my JS controller I am using the following code
uploadHelper : function(component, event, helper) {
var fileInput = component.find("fileId").get("v.files");
var input = component.get("v.fileList");
for (var i = 0; i < fileInput.length; i++) {
var file = fileInput[i];
console.log('*****'+file.name);
var self = this;
// create a FileReader object
var objFileReader = new FileReader();
objFileReader.onload = $A.getCallback(function() {
var fileContents = objFileReader.result;
var base64 = 'base64,';
var dataStart = fileContents.indexOf(base64) + base64.length;
fileContents = fileContents.substring(dataStart);
// call the uploadProcess method
self.uploadProcess(component, file, fileContents);
});
objFileReader.readAsDataURL(file);
}
},
Here in both the console.logs file names, if I upload 2 attachments, file names are being displayed properly for each iteration. However, if I check the uploaded file, I will see one of the files get uploaded twice. What am I doing wrong here
Updated Code
uploadHelper : function(component, event, helper) {
var fileInput = component.find("fileId").get("v.files");
[].forEach.call(fileInput, function(file) { readFile(file); });
},
readFile: function(component, file) {
var objFileReader = new FileReader();
objFileReader.onload = $A.getCallback(function() {
var fileContents = objFileReader.result;
var base64 = 'base64,';
var dataStart = fileContents.indexOf(base64) + base64.length;
fileContents = fileContents.substring(dataStart);
// call the uploadProcess method
self.uploadProcess(component, file, fileContents);
});
objFileReader.readAsDataURL(file);
},
Best Answer
Because of how closures work, the objFileReader is being overwritten each loop, so you're really only referencing the same object by the time the files get loaded. What you need to do is isolate the reader object in its own closure.
This wasn't covered in the example code, because it presumes that only one file at a time will be selected.