Uploading Over 500 Files Asynchronously From Visualforce


In this blog post, I will present a method for the asynchronous uploading of more than 500 files from a Visualforce page. This approach ensures that the failure of one file does not impact the upload of other files and effectively circumvents Salesforce’s CPU time limits.

Salesforce offers the apex:inputfile tag for file uploads from Visualforce pages. When utilizing this tag to upload multiple files, the process typically occurs within a single transaction, with files being uploaded sequentially.

Here’s an example to illustrate the standard process:

Uploading Parent Records Asynchronously


To begin, it is necessary to create parent records for the files that will be attached later. Instead of saving 500 records in a single insert operation, a remote action can be employed to insert each record asynchronously.

Explore the provided code sample below:

Controller
@RemoteAction
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++){
Visualforce.remoting.Manager.invokeAction(
               ‘{!$RemoteAction. UploadController. insertDocParent }’,
               ‘File Name’,
               handleResult
           );
   }
}
function handleResult(result, event) {
   uploadOneFile(result);
}

The saveParentRecord function will invoke the remoteAction method in the controller 500 times to insert the records. Since it is a remote action, all operations are asynchronous. This guarantees that the success or failure of each record won’t impact other records. The handleResult function serves as a callback to receive the result of each insert and subsequently calls the uploadOneFile function, responsible for the actual file upload process.

Uploading Files Asynchronously

Upon the creation of each parent record, the upload function is triggered independently of the completion of other parent record insertions. The uploadOneFile function employs the Salesforce API to facilitate file uploads. This process involves converting files to Base64 strings for uploading. The uploadOneFile function takes the parentId as a parameter, returned by the callback function from the remoteAction method, and assigns it to the new file record.

The code for the uploadOneFile function is provided below:

 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();
                                       sforce.connection.create([att],{
                                               onSuccess : function(result, source){  console.log(“Succeed”);},
                                               onFailure : function(error, source){console.log(“Failed”); }
                                       });
                           }
                           reader.readAsArrayBuffer(file);
}  
Subsequent Steps

The aforementioned steps conclude the upload of 500 files. Leveraging the callback functionality provided by the Salesforce API enables additional actions. In the onSuccess section, further processing of the file can be executed, such as sending an email notification to relevant stakeholders regarding the upload. Meanwhile, the onFailure section facilitates error handling, allowing the display of error messages back on the Visualforce page.

The use of Salesforce API and remoteAction empowers the asynchronous processing of more than 500 files. This proves particularly advantageous on the Salesforce platform given its numerous limitations. Moreover, the individual handling of each file is facilitated, ensuring that the upload process remains independent for each file without impacting others.

We trust that this post proves beneficial! If you have any queries, feel free to reach out to us with a message.