1

I have created a custom file upload component using a guide found online, I would like to extend the functionality to show a list of files currently uploaded to the record (which I have already built).

I would like to know how I can have the 'Files Upload' section reload on successful upload?

Component

<aura:attribute name="recordId" type="Id" />

<aura:handler event="aura:waiting" action="{!c.waiting}"/>
<aura:handler event="aura:doneWaiting" action="{!c.doneWaiting}"/>

<div class="container">

    <input type="file" class="file" aura:id="file" />
    <ui:button class="slds-button slds-button_brand" label="Upload File" press="{!c.save}"/>

    <div aura:id="uploading" class="notUploading">
        <img src="/auraFW/resources/aura/images/spinner.gif" alt="uploading" class="small-spinner" /> Uploading...
    </div>
</div>

<aura:attribute name="AttachmentList" type="Attachment[]"/>
<aura:handler name="init" value="{!this}" action="{!c.getMyAttachments}" />

<div class="container">
    <h3>Files Uploaded</h3>
    <!-- <p class="no-files">You havent uploaded any files yet.</p> -->

    <ul class="uploaded-files">
        <aura:iteration var="file" items="{!v.AttachmentList}">
            <li>{!file.Name}</li>
        </aura:iteration>
    </ul>

</div>

fileUploadController.js

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

    waiting: function(component, event, helper) {
        $A.util.addClass(component.find("uploading").getElement(), "uploading");
        $A.util.removeClass(component.find("uploading").getElement(), "notUploading");
    },

    doneWaiting: function(component, event, helper) {
        $A.util.removeClass(component.find("uploading").getElement(), "uploading");
        $A.util.addClass(component.find("uploading").getElement(), "notUploading");
        self.getMyAttachments;
    },

    getMyAttachments: function(component){
        var action = component.get("c.Attachments");
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.AttachmentList", response.getReturnValue());
            }
        });
        $A.enqueueAction(action);
    }

})

fileUploadHelper.js

({
    MAX_FILE_SIZE: 4 500 000, /* 6 000 000 * 3/4 to account for base64 */
    CHUNK_SIZE: 950 000, /* Use a multiple of 4 */

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

        if (file.size > this.MAX_FILE_SIZE) {
            alert('File size cannot exceed ' + this.MAX_FILE_SIZE + ' bytes.\n' +
              'Selected file size: ' + file.size);
            return;
        }

        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 fromPos = 0;
        var toPos = Math.min(fileContents.length, fromPos + this.CHUNK_SIZE);

        // start with the initial chunk
        this.uploadChunk(component, file, fileContents, fromPos, toPos, '');   
    },

    uploadChunk : function(component, file, fileContents, fromPos, toPos, attachId) {
        var action = component.get("c.saveTheChunk"); 
        var chunk = fileContents.substring(fromPos, toPos);

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

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

            fromPos = toPos;
            toPos = Math.min(fileContents.length, fromPos + self.CHUNK_SIZE);

            if (fromPos < toPos) {
                self.uploadChunk(component, file, fileContents, fromPos, toPos, attachId);  
            }
        });

        $A.run(function() {
            $A.enqueueAction(action); 
        });
    }
})

1 Answer 1

2

When you are done with uploading, just update your AttachmentList Attribute, therefore you could easily move your getMyAttachments method to your helper

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

and now you can call it whenever you are done uploading your chunks. After updating your list, all affected components will re-render and display your changes automatically.

So if I understand your recursion right you would need to add an else to your recursive ìf`:

if (fromPos < toPos) {
    self.uploadChunk(component, file, fileContents, fromPos, toPos, attachId);  
}
else {
    self.updateMyAttachments(component);
}
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .