The standard lightning component will upload the file and will have an 'Add' button once you click it, it will save the attachment. For my requirement I want user to only upload the file and then user have the option to save it. The way it works in custom lightning upload.Is it possible using below:

<lightning:fileUpload label="Attach receipt"
        accept=".pdf, .png"
        onuploadfinished="{!c.handleUploadFinished}" />

From the document of lightning:fileUpload it looks like its not possible. As soon as you select file it will just upload the content version on the reccordId. You have to use lightning:input but it have its own set of limits.

| improve this answer | |
  • Thank you for your response. The only Limit I can think of is, it has its size limit to 4.5 mb. correct? – Ruchit612 Aug 20 '19 at 19:55

Here is the workaround:

  1. When you upload the file, it will always create 2 content Document Links - 1 for userId and 1 for Record in which you are uploading.

  2. So, by default you can always give the recordId as the in-context user against whom a single content document link will be created.

  3. After upload, you will get the details of uploaded file(s).

  4. Then, on click of Save button, you can create another content document link against which you want to upload the file(s).

You can refer to https://github.com/sasank-sfdcdev/public/tree/master/src/lwc/upload for code as a sample


Store the files you get from onuploadfinished and pass them as an array (even single file) to below apex method.

You can use below apex method to create new links:

You need to pass the parameters:

    params: {
        files: '', // array of files uploaded against user 
        recordId: 'XXX' // recordId against which the document has to be shared. This file will start showing in that record files related list


public static List<ContentDocumentLink> createDocumentLink(Map<String, Object> params) {
    system.debug('params => '+params);
    List<Object> files = (List<Object>)params.get('files');
    String recordId = (String)params.get('recordId');
    List<ContentDocumentLink> cdLinks = new List<ContentDocumentLink>(); 

    for(Object file : files) {
        Map<Object,Object> fileMap = (Map<Object,Object>)file;
        cdLinks.add(new ContentDocumentLink(

    insert cdLinks;
    return cdLinks;
| improve this answer | |
  • Won't that still consume storage and have chances of unused files? – Pranay Jaiswal Aug 21 '19 at 7:06
  • Yes, it will still consume storage and will show 2 files in Attachment and File related list, which I don't want. – Ruchit612 Aug 21 '19 at 8:07
  • PLs read point 1, its the standard way upload works. We are just breaking that. In file related list, it will show only 1 (exactly the way standard works) – salesforce-sas Aug 21 '19 at 8:09
  • I didn't understand your point exactly, what will happen with the existing content document link? – Ruchit612 Aug 21 '19 at 8:22
  • Each and every file uploaded will have a link for the user who uploaded it. – salesforce-sas Aug 21 '19 at 8:27

I had to resolve a similar problem recently, and I could succeed by using the lightning:input component and giving it the type "file" :

<lightning:input type="file" aura:id="file" label="Add a document" variant="label-inline" name="file" onchange="{! c.handleDocumentSelected }"/>    

This component only performs the selection of the document. The fetch and storage is performed by the following code (credits: MDN):

//NB: this code is located in the Helper
loadAttachment: function( component, event ) {         

    //-- Attribut 'files' présent sur les lightning:input de type 'file'
    var files = event.getSource().get("v.files")

    if( files.length > 0 )  {
        var fileReader = new FileReader();  

        var file = files[0];            
        fileReader.onload = function () {                
            component.set("v.fileName", file.name);
            var fileContentBase64 = fileReader.result.split('base64,')[1]; 
            component.set("v.document", fileContentBase64);

The selected file is fetched from the hidden attribute "files" of the lightning:input component (which exists only for type="file" input component). The code retrieves it asynchronously using the onLoad() event and after some base64 conversion, stores it in a lightning:attribute "v.document".

Once you stored it, you can do whatever you want with it, especially link it with any Parent record you like. You need an Apex controller for that:

    public static void saveAttachment(Id factureId, String fileName, String fileContentBase64)  {
        ContentVersion contentVers = new ContentVersion();
        contentVers.ContentLocation = 'S'; // S specify this document is in SF, use E for external files
        contentVers.PathOnClient = fileName; 
        contentVers.Title = fileName;
        contentVers.VersionData = EncodingUtil.base64Decode(fileContentBase64); // contentVersting your binary string to Blog
        insert contentVers;

        // First get the content document Id from ContentVersion
        Id contentDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:contentVers.Id].ContentDocumentId;

        //Create ContentDocumentLink
        ContentDocumentLink contentLink = new ContentDocumentLink();
        contentLink.ContentDocumentId = contentDocId;
        contentLink.LinkedEntityId = factureId; 
        contentLink.ShareType = 'I'; // Inferred permission
        contentLink.Visibility = 'AllUsers';
        insert contentLink;

Check it out !!!

| improve this answer | |

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.