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.

  • Do you change the file between the two clicks? – Martin Lezer Jun 30 '17 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. – Aditya Vijay Jun 30 '17 at 11:20
  • 1
    while calling upload method set some delay using setTimeout and try it.. – vignesh Jun 30 '17 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. – Aditya Vijay Jul 4 '17 at 12:41
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.