1

I am implementing uploading files from lightning component on click of a button, but lightning to apex controller request goes every second time only. Here is the code I am trying-

Component-

<input type="file" class="" accept="image/*" id="file1" aura:id="file" />
<input onclick="{!c.save}" value="Upload" style="float:right" class="slds-button slds-button--brand" />

Controller

save: function(component, event, helper) {
    var fileInput = component.find("file").getElement();
    var file = fileInput.files[0];
    var fr = new FileReader();
    fr.onload = function() {
         console.log('filereader');
         var fileContents = fr.result;
         var base64Mark = 'base64,';
         var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length;
         fileContents = fileContents.substring(dataStart);
         helper.upload(component, file, fileContents);
    };
    fr.readAsDataURL(file);
});

Helper-

upload: function(component, file, fileContents) {
    var action = component.get("c.saveTheFile"); 

    action.setParams({
        fileName: file.name,
        base64Data: encodeURIComponent(fileContents), 
        contentType: file.type
    });
    console.log('upload');
    action.setCallback(this, function(response) {
        console.log('callback');
    });
    $A.enqueueAction(action);
}

Output- First time button click prints-
filereader
upload

Second time button click prints-
filereader
upload
filereader
upload
callback
callback

As the console shows, 2 files are being saved every second time I am pressing the button.

4
  • Do you change the file between the two clicks? Commented Jun 30, 2017 at 11:15
  • @MartinLezer not at all! I select a file in file dialog, then click the button and output is as I mentioned in the question. Commented Jun 30, 2017 at 11:20
  • 1
    while calling upload method set some delay using setTimeout and try it..
    – vignesh
    Commented Jun 30, 2017 at 11:31
  • @vignesh Eventually had to do that as I knew this hack, just wondering if something better was there, will check the answer as well. Commented Jul 4, 2017 at 12:41

1 Answer 1

1

Wrap your oncall function in $A.getCallback. For example:

fr.onload = $A.getCallback(function onloadCallback() {
   ... callback code here ...
};

I remember having a similar problem, and wrapping the callback in $A.getCallback fixed it for me.

You must log in to answer this question.

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