0

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);
},
2
  • This code is in the controller? Are you sure? I'd expect the upload to fail entirely if this was the case, as this is undefined in a controller.
    – sfdcfox
    Commented Nov 8, 2018 at 20:24
  • No it does not fail. One of the attachments get uploaded
    – Madhurima
    Commented Nov 8, 2018 at 20:25

1 Answer 1

1

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.

readFile: function(component, file) {
  var reader = new FileReader();
  var self = this;
  reader.onload = $A.getCallback(function() {
    ...
  });
  reader.readAsDataURL(file);
},
uploadHelper: function(component, event, helper) {
  var fileInput = component.find("fileId").get("v.files");
  [].forEach.call(fileInput, function(file) { readFile(file); });
},
...

This wasn't covered in the example code, because it presumes that only one file at a time will be selected.

2
  • I have made changes in the code like you described. But it is not working either. I have updated the changed code in my question above.
    – Madhurima
    Commented Nov 8, 2018 at 21:22
  • user55791 ,i need to same requirement, could please explain multiple files how to upload ?
    – srija
    Commented Dec 27, 2019 at 6:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .