3

I am attempting to create a Lightning Component Custom Action to upload an attachment to a Salesforce record. It is based on Peter Knolle's blog post: http://peterknolle.com/file-upload-lightning-component/

Currently, I am able to select a file, read the file, and queue the 'saveTheFile' action by pressing the Save button. However, the action does not execute (get sent to the server) until I hit the Save button again, at which time the Component processes both actions and uploads two copies of the file.

My question/request is for more insight into why this may happen. I am new-ish to Javascript and the Lightning Component Framework, and my research thus far has proven fruitless.

Below is a simplified version of my code. Thank you in advance for support on my Lightning Component journey!

Component

<aura:component controller="FileController" implements="force:lightningQuickAction,force:hasRecordId,force:appHostable">
<div>
    <input type="file" class="file" aura:id="file" />
    <ui:button label="Save" press="{!c.save}"/>
</div>    
</aura:component>

JS Controller

({  
save : function(component, event, helper) {
    helper.save(component);
},

waiting: function(component, event, helper) {
    console.log('waiting');
},

doneWaiting: function(component, event, helper) {
    console.log('done waiting');
}
})

Helper

({
save : function(component) {
    var fileInput = component.find("file").getElement();
    var file = fileInput.files[0];

    var fr = new FileReader();

    var self = this;
    fr.onload = function() {
        var fileContents = fr.result;
        var base64Mark = 'base64,';
        var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length;

        fileContents = fileContents.substring(dataStart);

        self.upload(component, file, fileContents);
    };

    fr.readAsDataURL(file);
},

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

    action.setParams({
        parentId: component.get("v.recordId"),
        fileName: file.name,
        base64Data: encodeURIComponent(fileContents), 
        contentType: file.type
    });

    action.setCallback(this, function(a) {
        var attachId = a.getReturnValue();
    });

    $A.enqueueAction(action);
}
})

Apex Controller

public class FileController {

    @AuraEnabled
    public static Id saveTheFile(Id parentId, String fileName, String base64Data, String contentType) { 
    base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');

    Attachment a = new Attachment();
    a.parentId = parentId;

    a.Body = EncodingUtil.base64Decode(base64Data);
    a.Name = fileName;
    a.ContentType = contentType;

    insert a;

    return a.Id;
    }
}

I tried wrapping fr.onload inside $A.getcomponent like following.

$A.getCallback(function() {

 fr.onload = function() {

        var fileContents = fr.result;
        var base64Mark = 'base64,';
        var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length;

        fileContents = fileContents.substring(dataStart);

        self.upload(component, file, fileContents,personelIdentType);
      };
});
fr.readAsDataURL(file);

But it seems either syantax for $A.getcomponent() is wrong or i need to do something else.Please help me out.

  • 2
    Try wrapping the onload callback within $A.getCallback(). Eg: fr.onload = $A.getCallback(function() { ...}). It might be due to the fact the callback is being called out of Aura's execution context. – Praveen Jan 3 '17 at 19:18
  • @Praveen, unfortunately that didn't affect the behavior. – SpeedDaemon Jan 3 '17 at 19:29
  • With $A.getCallback added, your code works perfectly. Try putting console.log(attachId,a.getState()) inside the callback of the server action:saveTheFile – Praveen Jan 3 '17 at 19:34
  • SpeedDaemon, what does your console.log prints out when you click save button – Praveen Jan 3 '17 at 19:49
  • I just figured it out. Apparently my LastPass Chrome extension was interfering with the ActionService. I disabled the extension and now the code works as expected. I ran into a similar issue recently when integrating Salesforce with Quickbooks. Any thoughts on the exact issue that a Chrome extension could have on the ActionService? – SpeedDaemon Jan 3 '17 at 19:55
0

I had the same issue and it worked by wrapping onload into $A.getCallback()

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.