How to Asynchronously Upload More Than 500 Files from VisualForce

In this blog post, I will introduce a way to asynchronously upload more than 500 files from a VisualForce page which means the failure of one file will not affect the upload of other files and it will bypass the CPU time limits of Salesforce.

Salesforce provides apex:inputfile tag for uploading files from a VisualForce page. When you upload a bunch of files using this tag, all these files are uploaded in one transaction and they are uploaded one by one.

Here is an example to explain how it works:

Asynchronously Uploading: Create Parent Records

First of all, we need to create parent records for the files to be attached to later. Rather than saving 500 records using one insert, we can use remote action to insert each of the record asynchronously.

Check out the following code sample:

global static String insertDocParent(String fileName){
Parent_Object__c parent = new Parent_Object__c();
parent.Name = filename;
insert parent;
       return parent.Id;
VF Page
function saveParentRecord(){
   Visualforce.remoting.timeout = 120000;
for(i=0; i<500; i++){
               ‘{!$RemoteAction. UploadController. insertDocParent }’,
               ‘File Name’,
function handleResult(result, event) {

The saveParentRecord function will call 500 times the remoteAction method in the controller to insert the records. As it is remote action, so they are all asynchronous. This will ensure each record’s failure or success won’t affect other records. The handleResult function is a callback function to receive the result of each insert and do the next step to call the uploadOneFile function which is doing the real upload of file.

Asynchronously Uploading: Upload File

Whenever a parent record is created, the upload function will be called to upload the file. It won’t wait for other parent record insertion to be completed. The uploadOneFile function utilises the Salesforce API to upload file. It converts files to Base64 string and upload. The uploadOneFile will get the parentId as a parameter (return by the callback function from remoteAction method) and assign it to the new file record. Below is the code for uploadOneFile function:

 function uploadOneFile(parentId){
                            var filesToUpload = allFiles;
                            var file = filesToUpload[0];
                            var reader = new FileReader();
                            reader.file = file;
                            reader.onload = function(e){
                                        var att = new sforce.SObject(“FeedItem”);
                                        att.ContentFileName = this.file.name.replace(/\s+/g, ” “);
                                        att.ParentId  = parentId;
                                        att.Visibility = ‘AllUsers’;
                                        var binary = “”;
                                       var bytes = new Uint8Array(e.target.result);
                                       var length = bytes.byteLength;
                                       for (var i = 0; i < length; i++){
                                           binary += String.fromCharCode(bytes[i]);
                                       att.ContentData = (new sforce.Base64Binary(binary)).toString();
                                               onSuccess : function(result, source){  console.log(“Succeed”);},
                                               onFailure : function(error, source){console.log(“Failed”); }

Further Process

The above will finish the upload of 500 files. As the Salesforce API provides callback functionality, we can do even more. In the onSuccess section, we can further process the file, for example send out an email about the upload to interested party. In the onFailure section, we can do some error handling to display error message back to the VisualForce page.

With the help of Salesforce API and remoteAction, we are able to process more than 500 files asynchronously. This is particularly valuable for the Salesforce platform as there are so many limits. It also allows the separation of each file, so the upload can be handled individually without affecting any other files.

Hope this post was helpful! If you have questions, feel free to hit us up with a message!


Add a Comment

Your email address will not be published.