Hey Coder, Today we will build Custom file uploader in LWC
When we use lightning-file-upload it directly upload file to ContentDocument object and we don’t have control on before upload activities. See how to build basic file uploader.
If we want to upload file to precise location we have to use lighting-input with type file.
In this post we will build Custom file uploader which will upload file to specific folder in lightning-file-upload object.
Quick Demo
What you will learn?
- Get Document folder/workspace Id in apex
- How to use ContentVersion and Insert file
- How to get current recordId in lightning web component
- How to use lighting-input to upload file
- Call apex method form LWC and upload file
- Handle file upload in LWC
- Show Toast message on Success/Error
Lets see some important code snippet.
How to get Folder/Workspace Id
private static Id getLibraryIdByName(String libraryName) {
List<ContentWorkspace> libraries = [SELECT Id FROM ContentWorkspace WHERE Name = :libraryName LIMIT 1];
if (!libraries.isEmpty()) {
return libraries[0].Id;
}
return null;
}
Lighting input type File
<lightning-input type="file" label="Select File" onchange={handleFileChange} accept="image/png"></lightning-input>
Complete LWC and Apex Code to Upload File In Folder
- Apex Class
- HTML file
- JS file
- XML file
Find all four files below:
1: Apex Class
public with sharing class LWCFileUpload {
@AuraEnabled
public static string uploadFileAndGenerateLink(String fileName, String fileContent) {
String libraryName = 'My SF Data Center';
Id libraryId = getLibraryIdByName(libraryName);
if (libraryId == null) {
throw new AuraHandledException('Library not found: ' + libraryName);
}
ContentVersion contentVersion = new ContentVersion();
contentVersion.Title = fileName;
contentVersion.PathOnClient = fileName;
contentVersion.VersionData = EncodingUtil.base64Decode(fileContent);
contentVersion.FirstPublishLocationId = libraryId;
insert contentVersion;
return null;
}
private static Id getLibraryIdByName(String libraryName) {
List<ContentWorkspace> libraries = [SELECT Id FROM ContentWorkspace WHERE Name = :libraryName LIMIT 1];
if (!libraries.isEmpty()) {
return libraries[0].Id;
}
return null;
}
}
2: HTML File
<template>
<lightning-card title="Upload File to Folder" icon-name="custom:custom63">
<lightning-input type="file" label="Select File" onchange={handleFileChange} accept="image/png"></lightning-input>
<br>
<lightning-button label="Upload" onclick={handleFileUpload} class="slds-m-top_medium"></lightning-button>
<template if:true={publicLink}>
<lightning-input label="Public Link" value={publicLink} readonly></lightning-input>
</template>
</lightning-card>
</template>
3: JS File
import { LightningElement, api, track } from 'lwc';
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import uploadFileAndGenerateLink from '@salesforce/apex/LWCFileUpload.uploadFileAndGenerateLink';
export default class UploadFIleToFolder extends LightningElement {
fileData;
@api recordId;
handleFileChange(event) {
const file = event.target.files[0];
if (file) {
this.fileData = {
fileName: file.name,
fileContent: ''
};
const reader = new FileReader();
reader.onload = () => {
const base64 = reader.result.split(',')[1];
this.fileData.fileContent = base64;
};
reader.readAsDataURL(file);
}
}
handleFileUpload() {
if (this.fileData) {
uploadFileAndGenerateLink({ fileName: this.fileData.fileName, fileContent: this.fileData.fileContent })
.then(result => {
this.showToast('Success', 'Image uploaded to Account Images', 'success')
})
.catch(error => {
this.showToast('Error', 'Error uploading file', 'error')
});
}
}
showToast(title, message, variant) {
const evt = new ShowToastEvent({
title: title,
message: message,
variant: variant,
});
this.dispatchEvent(evt);
}
}
4: XML Config File
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>56.0</apiVersion>
<isExposed>true</isExposed>
<masterLabel>Upload File to Folder</masterLabel>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>