1

Trying to upload multiple files using lightning component. I upload multiple files same file name create multiple time.(not working properly)

This is my code: could you please help on this?

Apex Controller:

public with sharing class FileUploadController {


    @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('0012v00002aIYgy', 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 = '0012v00002aIYgy';

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

        insert oAttachment;

        return oAttachment.Id;
    }


}

Lighhtning Component:

<aura:component controller="FileUploadController">
 <!-- 'parentId' Aura Attribute for store the Id for Parent Record where we are attach our file -->  
   <aura:attribute name="parentId" type="Id" default="0016F000024nYzwQAE" />
 <!-- 'showLoadingSpinner' attribute for show/hide the uploading image and msg in aura:if-->
   <aura:attribute name="showLoadingSpinner" type="boolean" default="false" />
 <!-- 'fileName' attribute for display the selected file name -->  
   <aura:attribute name="fileName" type="String" default="No File Selected.." />
 <!-- Lightning Input with file type and on file change call the 'handleFilesChange' controller --> 

   <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>
</aura:component>

Controller.js:

({
    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);
    },
})

Helper.js:


 ({
    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]  

        for(var i = 0; i < fileInput.length; i++){

            //alert(JSON.stringify(fileInput[i]));

            var file = fileInput[i];
        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,
                //fileName:'RaghuUpload',
                base64Data: encodeURIComponent(getchunk),
                contentType: file.type,
                //contentType: '.pptx',
                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);
        }
    })

Lightning application :

<aura:application extends="force:slds">
    <c:fileUpload/>
<!-- here c: is org. default namespace prefix-->
</aura:application>

1 Answer 1

1

Problem is at FileReader object creation. Try to change helper and apex controller like below. It will wotk.

Helper.js

  ({
    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]  
        for(var i = 0; i < fileInput.length; i++){
            var file = fileInput[i];
            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;
            }
            self.uploadFile(component, file);
        }

    },
    uploadFile:function(component, file) {
            var self = this;
           // 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) {
        var self = this;
        // 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,
            //fileName:'RaghuUpload',
            base64Data: encodeURIComponent(getchunk),
            contentType: file.type,
            //contentType: '.pptx',
            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);
    }
})

Apex:

public with sharing class FileUploadController {

    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;
    }

    @AuraEnabled
    public static Id saveChunk(Id parentId, String fileName, String base64Data, String contentType, String fileId) {
        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;
    }


}
1
  • Dhanik Lal Sahni,Thank you very much its working good Commented Dec 27, 2019 at 11:10

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.