function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Narendra Reddy 13Narendra Reddy 13 

Multiple file upload not working in lightning component?

Hi Everyone,
I am new to lightning component, i have written code for upload multiple files upload. But for me working only single file upload. Can anybody help me to resolve this issue. Below are the code details:
Apex Controller:
public with sharing class overrideStandabuttonwithLC {
     @AuraEnabled
    public static ID saveAccount(RFP_Request__c accRec, RFP_Request__c rfplkp)
    {
        try
        {
            accRec.RFP_Manager__c=rfplkp.RFP_Manager__c;
            insert accRec;
        }
        catch(Exception e)
        {
            system.debug('e-->' + e.getMessage());
        }
        
        return accRec.Id;
    } 
    @AuraEnabled
    public static Id saveChunk(Id parentId, String fileName, String base64Data, String contentType, String fileId) {
        // check if fileId id ''(Always blank in first chunk), then call the saveTheFile method,
        //  which is save the check data and return the attachemnt Id after insert, 
        //  next time (in else) we are call the appentTOFile() method
        //   for update the attachment with reamins chunks   
        if (fileId == '') {
            fileId = saveTheFile(parentId, fileName, base64Data, contentType);
        } else {
            appendToFile(fileId, base64Data);
        }
         return Id.valueOf(fileId);
    }
     public static Id saveTheFile(Id parentId, String fileName, String base64Data, String contentType) {
        base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
         Attachment oAttachment = new Attachment();
        oAttachment.parentId = parentId;
         oAttachment.Body = EncodingUtil.base64Decode(base64Data);
        oAttachment.Name = fileName;
        oAttachment.ContentType = contentType;
         insert oAttachment;
         return oAttachment.Id;
    }
     private static void appendToFile(Id fileId, String base64Data) {
        base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
         Attachment a = [
            SELECT Id, Body
            FROM Attachment
            WHERE Id =: fileId
        ];
         String existingBody = EncodingUtil.base64Encode(a.Body);
         a.Body = EncodingUtil.base64Decode(existingBody + base64Data);
         update a;
    } 
  }
Component:
<aura:component implements="lightning:actionOverride,force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" controller="overrideStandabuttonwithLC">
    
    <aura:attribute name="rfp" type="RFP_Request__c" default="{'sobjectType': 'RFP_Request__c'}" />
    <aura:attribute name="silookup" type="sObject" default="{}"/> 
    <aura:attribute name="sample" type="String" default="Pranamics"/>
    <aura:attribute name="parentId" type="Id" />
    <aura:attribute name="showLoadingSpinner" type="boolean" default="false"/>
    <aura:attribute name="fileName" type="String" default="No File Selected.." />
    <aura:handler name="init" value="{!this}" action="{!c.onload}"/>
    <div class="slds-page-header css-slider-wrapper">
        
        <div class="slds-page-header css-slider-wrapper">
            <div class="slds-grid css-slider-wrapper">
                <div class="slds-col css-slider-wrapper slds-has-flexi-truncate">
                    <center> <p class="slds-text-heading--label"><b>New RFP Request</b></p></center>
                    <div class="slds-grid css-slider-wrapper">
                        <div class="slds-m-around--medium">
                            <center><button class="slds-button slds-button--brand" onclick="{!c.createrfprequ}">Save</button></center>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="slds-page-header">
            <div class="slds-grid">
                <div class="slds-col slds-has-flexi-truncate">
                    <p class="slds-text-heading--label">RFP Request Information</p>
                    <div class="slds-grid">
                     </div>
                </div>
            </div>
        </div>
                <div class="slds-page-header css-slider-wrapper">
            <div class="slds-grid css-slider-wrapper">
                <div class="slds-col slds-has-flexi-truncate css-slider-wrapper">
                    <div class="slds-form-element__control css-slider-wrapper">
                        <lightning:layout horizontalAlign="space">
                            
                            <lightning:layoutitem padding="around-small" flexibility="auto" >
                                <ui:inputText label="Name" value="{!v.rfp.Name}" class="slds-input" required="true"/>
                                <ui:inputText aura:id="Issued_By__c" label="Issued Company" value="{!v.rfp.Issued_By__c}" class="slds-input" required="true"/>
                                <ui:inputText aura:id="Representative_Name__c" label="Representative Name" value="{!v.rfp.Representative_Name__c}" class="slds-input" required="true"/>
                                <ui:inputText aura:id="Representative_Email_Id__c" label="Representative Email Id" value="{!v.rfp.Representative_Email_Id__c}" class="slds-input" required="true"/> 
                                <ui:inputText aura:id="Representative_Phone__c" label="Representative Phone" value="{!v.rfp.Representative_Phone__c}" class="slds-input" required="true"/>
                            </lightning:layoutitem>
                            
                            <lightning:layoutitem padding="around-small" flexibility="auto" >
                                <div>* RFP Manager</div>
                                <c:customlookup objectAPIName="user" IconName="standard:user" selectedRecord="{!v.silookup}"/>
                                <ui:inputDate aura:id="Issued_Date__c" label="Issued Date" value="{!v.rfp.Issued_Date__c}" class="slds-input" displayDatePicker="true" required="true"/>
                                <ui:inputDate aura:id="Dead_Line_Date__c" label="Deadline Date" value="{!v.rfp.Dead_Line_Date__c}" class="slds-input" displayDatePicker="true" required="true"/>
                            </lightning:layoutitem>
                        </lightning:layout>
                    </div>
                    <div class="slds-grid">
                    </div>
                </div>
            </div>
        </div>
        <div class="slds-page-header" role="banner">
            <lightning:input aura:id="fileId" onchange="{!c.handleFilesChange}" type="file" name="file" label="Upload Attachment" multiple="true"/>
            <div class="slds-text-body_small slds-text-color_error">{!v.fileName} </div>
            
            <!--use aura:if for show-hide the loading spinner image--> 
            <aura:if isTrue="{!v.showLoadingSpinner}">
                <div class="slds-text-body_small slds-text-color_error">Uploading... 
                    <img src="/auraFW/resources/aura/images/spinner.gif" class="spinner-img" alt="Loading"/>
                </div>
            </aura:if>
            <br/>
            <!-- <button class="slds-button slds-button_brand" onclick="{!c.doSave}">Upload Attachment</button>-->    
        </div>
        
        
        <div class="slds-m-around--medium">
            <center><button class="slds-button slds-button--brand" onclick="{!c.createrfprequ}">Save</button></center>
        </div>
    </div>
</aura:component>

JS Controller:
({
    onload : function(component, event, helper) 
    {
        
    },
    createrfprequ : function(component, event, helper) 
    {
        var action = component.get("c.saveAccount");
        var rfp = component.get("v.rfp");
        
        var name = JSON.stringify(component.get("v.rfp.Name"));
        if($A.util.isEmpty(name) || $A.util.isUndefined(name))
        {
            alert('Please enter a name.');
            return;
        }
        if($A.util.isEmpty(rfp.Issued_By__c) || $A.util.isUndefined(rfp.Issued_By__c))
        {
            alert('Please enter a Issued Company.');
            return;
        }
        if($A.util.isEmpty(rfp.Representative_Name__c) || $A.util.isUndefined(rfp.Representative_Name__c))
        {
            alert('Please enter a Representative Name.');
            return;
        }
        if($A.util.isEmpty(rfp.Representative_Email_Id__c) || $A.util.isUndefined(rfp.Representative_Email_Id__c))
        {
            alert('Please enter a Representative Email Id.');
            return;
        }
        
        if($A.util.isEmpty(rfp.Representative_Phone__c) || $A.util.isUndefined(rfp.Representative_Phone__c))
        {
            alert('Please select a Representative Phone.');
            return;
        }
        if(component.get("v.silookup").Id == undefined)
        {
            alert('Please select a RFP Manager.');
            return;
        }
        
        if($A.util.isEmpty(rfp.Issued_Date__c) || $A.util.isUndefined(rfp.Issued_Date__c))
        {
            alert('Please select an Issued Date.');
            return;
        }
        
        if($A.util.isEmpty(rfp.Dead_Line_Date__c) || $A.util.isUndefined(rfp.Dead_Line_Date__c))
        {
            alert('Please select an Deadline Date.');
            return;
        }
         // file upload button 
        if (component.find("fileId").get("v.files").length > 0) 
        {
           
        } 
        else
        {
            alert('Please Select a Valid File');
            return;
        }                            
        rfp.RFP_Manager__c = null ; 
        
        if(component.get("v.silookup").Id != undefined){
            rfp.RFP_Manager__c = component.get("v.silookup").Id;
        }
           action.setParams({
            accRec:component.get("v.rfp"),
            rfplkp:rfp
        });
        
        action.setCallback(this, function(response)
         {
             if(response.getState()==='SUCCESS')
             {
                 var rfpid = response.getReturnValue();
                 
                 if (component.find("fileId").get("v.files").length > 0) 
                 {
                     helper.uploadHelper(component, event);
                 } 
                 component.set("v.parentId", rfpid); 
                 
                 var toastEvent = $A.get("e.force:showToast");
                 toastEvent.setParams({
                     "title": "Success!",
                     "type":"Success",
                     "message": "RFP Request has been created successfully."
                 });
                 toastEvent.fire();
                 
                 var navEvt = $A.get("e.force:navigateToSObject");
                 navEvt.setParams({
                     "recordId":  rfpid,
                     "slideDevName": "related"
                 });
                 navEvt.fire();
             }
         });
        $A.enqueueAction(action);
    },
    
    onCancel : function(component, event, helper) {
        
        // Navigate back to the record view
        var navigateEvent = $A.get("e.force:navigateToSObject");
        navigateEvent.setParams({ "recordId": component.get('v.recordId') });
        navigateEvent.fire();
    },
    
    doSave: function(component, event, helper) {
        if (component.find("fileId").get("v.files").length > 0) {
            helper.uploadHelper(component, event);
        } else {
            alert('Please Select a Valid File');
        }
    },
    
    handleFilesChange: function(component, event, helper) {
        var fileName = 'No File Selected..';
        if (event.getSource().get("v.files").length > 0) {
            fileName = event.getSource().get("v.files")[0]['name'];
        }
        component.set("v.fileName", fileName);
    },
   
})

 
Narendra Reddy 13Narendra Reddy 13
Helper:
({
    MAX_FILE_SIZE: 4500000, //Max file size 4.5 MB 
    CHUNK_SIZE: 750000,      //Chunk Max size 750Kb 
    
    uploadHelper: function(component, event) {
        // start/show the loading spinner   
        component.set("v.showLoadingSpinner", true);
        // get the selected files using aura:id [return array of files]
        var fileInput = component.find("fileId").get("v.files");
        // get the first file using array index[0]  
        var file = fileInput[0];
        var self = this;
        // check the selected file size, if select file size greter then MAX_FILE_SIZE,
        // then show a alert msg to user,hide the loading spinner and return from function  
        if (file.size > self.MAX_FILE_SIZE) {
            component.set("v.showLoadingSpinner", false);
            component.set("v.fileName", 'Alert : File size cannot exceed ' + self.MAX_FILE_SIZE + ' bytes.\n' + ' Selected file size: ' + file.size);
            return;
        }
 
        // create a FileReader object 
        var objFileReader = new FileReader();
        // set onload function of FileReader object   
        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);
    },
 
    uploadProcess: function(component, file, fileContents) {
        // set a default size or startpostiton as 0 
        var startPosition = 0;
        // calculate the end size or endPostion using Math.min() function which is return the min. value   
        var endPosition = Math.min(fileContents.length, startPosition + this.CHUNK_SIZE);
 
        // start with the initial chunk, and set the attachId(last parameter)is null in begin
        this.uploadInChunk(component, file, fileContents, startPosition, endPosition, '');
    },
 
 
    uploadInChunk: function(component, file, fileContents, startPosition, endPosition, attachId) 
    {
        // call the apex method 'saveChunk'
        var getchunk = fileContents.substring(startPosition, endPosition);
        var action = component.get("c.saveChunk");
        action.setParams({
            parentId: component.get("v.parentId"),
            fileName: file.name,
            base64Data: encodeURIComponent(getchunk),
            contentType: file.type,
            fileId: attachId
        });
 
        // set call back 
        action.setCallback(this, function(response) {
            // store the response / Attachment Id   
            attachId = response.getReturnValue();
            var state = response.getState();
            if (state === "SUCCESS") {
                // update the start position with end postion
                startPosition = endPosition;
                endPosition = Math.min(fileContents.length, startPosition + this.CHUNK_SIZE);
                // check if the start postion is still less then end postion 
                // then call again 'uploadInChunk' method , 
                // else, diaply alert msg and hide the loading spinner
                if (startPosition < endPosition) {
                    this.uploadInChunk(component, file, fileContents, startPosition, endPosition, attachId);
                } else 
                {
                    //alert('your File is uploaded successfully');
                    component.set("v.showLoadingSpinner", false);
                }
                // handel the response errors        
            } else if (state === "INCOMPLETE") {
                alert("From server: " + response.getReturnValue());
            } else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        // enqueue the action
        $A.enqueueAction(action);
    }
})
ashok sfdc 1ashok sfdc 1
Hi Narendra,

Have you got any output on the above scenario? I am facing the same issue to upload multiple files with the same code. Please help me if you have any solution on same or guide me the same.

Thanks,
Ashok SFDC