Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Lightning File Upload Component
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;
}
@AuraEnabled
public static Id saveTheChunk(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);
}
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;
}
}
<!-- fileUpload2.cmp is identical -->
<aura:component controller="paura.FileController">
<aura:attribute name="parentId" 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 label="Save" press="{!c.save}"/>
<div aura:id="uploading" class="notUploading">
<img src="/resource/paura__images/loading-gray.gif" alt="uploading" class="small-spinner" /> Uploading...
</div>
</div>
</aura:component>
/* fileUpload2.css is identical */
.THIS .notUploading {
visibility: hidden;
}
.THIS .uploading {
visibility: visible;
display: inline-block;
margin-top: 10px;
}
.THIS .small-spinner {
height: 20px;
width: 20px;
}
.THIS .file {
margin-bottom: 5px;
display: block;
}
/* fileUploadController2.js is identical */
({
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");
}
})
({
MAX_FILE_SIZE: 750 000, /* 1 000 000 * 3/4 to account for base64 */
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 action = component.get("c.saveTheFile");
action.setParams({
parentId: component.get("v.parentId"),
fileName: file.name,
base64Data: encodeURIComponent(fileContents),
contentType: file.type
});
action.setCallback(this, function(a) {
attachId = a.getReturnValue();
console.log(attachId);
});
$A.run(function() {
$A.enqueueAction(action);
});
}
})
({
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.parentId"),
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);
});
}
})
<!-- This is a simple app that shows how the component can be used.
The Id could be passed in via URL or some other mechanism.
This is just for testing.
-->
<aura:application>
<div class="container">
<!--<paura:fileUpload parentId="0013020s006DqaI"/>-->
<paura:fileUpload2 parentId="0013020s006DqaI"/>
</div>
</aura:application>
@vijaykumar8448

This comment has been minimized.

Copy link

commented Dec 10, 2015

How can we add a file which have file size 10 MB?

@vijaykumar8448

This comment has been minimized.

Copy link

commented Dec 11, 2015

HI Peter , How can we add a file which have file size 10 MB?

@lushang

This comment has been minimized.

Copy link

commented Mar 23, 2017

The code has two places to update BEFORE YOU USE IT:

  1. Change CHUNK_SIZE to a smaller number:
    CHUNK_SIZE: 450 000, /* Use a multiple of 4 */

  2. Add $A.getCallback() to the async file reader onload event:

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

            fileContents = fileContents.substring(dataStart);
       
    	    self.upload(component, file, fileContents);
        });
  1. Delete $A.run() since it's not supported anymore

Change

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

TO
$A.enqueueAction(action);

@johnc847

This comment has been minimized.

Copy link

commented Apr 20, 2017

How can I make the user load attachments when using this on a form?

@pvnjoy00

This comment has been minimized.

Copy link

commented Jun 18, 2017

why do you have 2 helper classes?

@Vickal

This comment has been minimized.

Copy link

commented Jun 25, 2017

I'm getting below error on save.
'TypeError: $A.run is not a function[Learn More] safeEval.html:63:9
VIC$FileUploadCompt.helper.upload components/VIC/FileUploadCompt.js:63:9
VIC$FileUploadCompt.helper.save/fr.onload'
Any Idea ?

@arun12209

This comment has been minimized.

Copy link

commented Aug 10, 2017

Hi @lushang, I have implemented this code to upload file size upto 4mb. But when i trying to upload file size 1.3mb getting error
'Input too long. [1, 173]' . Can you please help.

@rajanr1021

This comment has been minimized.

Copy link

commented Sep 5, 2017

Hi @lushang, After attachments are uploading twice for me after double clicking the save button.If i click once the save button i did not see anything is uploaded.Can you please assist on your code??

@badrianth

This comment has been minimized.

Copy link

commented Sep 22, 2017

hey iam getting below error please rectify........
aura_proddebug.js:24605 Uncaught TypeError: Cannot read property 'upload' of undefined
throws at components/c/upload.js:24:15 TypeError: Cannot read property 'upload' of undefined
at FileReader.fr.onload (components/c/upload.js:24)

@Satya738

This comment has been minimized.

Copy link

commented Nov 9, 2018

Hi Peter

How can we change the code to upload larger files. like 10 to 20MB files. I have tried increasing the MAX_FILE_SIZE but not worked for me. Getting below error. Please help me with uploading the larger files.

fileuploadissue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.