Upload Image, create public url and preview images in Lightning Web Component.

Posted on July 2, 2021 Post Thumbnail

Hey Trailblazers :)

In this blog post,

1. We're going to create a lightning component which provides a functionality to upload an image.

2. Create a public link of uploaded image.

3. Preview uploaded image and add public link to related parent record.

Sometimes we have a requirement:

We need to add an image to Salesforce Object and we need to save public link of that image in a field.

And we also need to preview any uploaded image. 

Have a look at following image.

Image

Thumbnail Image: Null

No image uploaded

After uploading.

After uploading an image, I can have public link in Thumbnail Image and able to preview uploaded.

What you'll Learn from Blog Post :)

1. Upload file component.

2. Difference between ContentVersion and ContentDistribution.

Start :)

Upload file Component:

            <lightning-input type="file" label="Upload File"></lightning-input>

ContentVersion:

We use ContentVersion for inserting a file.

Check following code:

        // inserting file
        ContentVersion cv = new ContentVersion();
        cv.Title = strFileName;
        cv.PathOnClient = '/' + strFileName;
        cv.FirstPublishLocationId = idParent;
        cv.VersionData = EncodingUtil.base64Decode(base64Data);
        cv.IsMajorVersion = true;
        Insert cv;

ContentDistribution:

We use ContentDistribution for sharing a file. In ContentDownloadUrl we reference ContentVersionId for sharing.

Check following code:

            ContentDistribution cdl = new ContentDistribution();
            cdl.ContentVersionId = ContentVersionId;
            cdl.Name = 'PublicShare';

After sharing, We query ContentDownloadUrl field from ContentDownloadUrl

ContentDownloadUrl is public url.

            String publicUrl = [SELECT DistributionPublicUrl, ContentDownloadUrl FROM ContentDistribution WHERE Id = :cdl.Id LIMIT 1].ContentDownloadUrl;

For Updating field, We add this publicUrl in field.

And for preview this image, We use following code:

               <lightning-card title="Thumbnail Image of the Product" icon-name="utility:image">
                    <div style="width: auto;">
                        <template if:false={data}>
                            <i class="slds-text-color_error">No image uploaded!</i>
                        </template>
                        <template if:true={data}>
                            <img src={data} width="150">
                        </template>
                    </div>
                </lightning-card>

All set :)

I'm using Product2 Object in this blog and using thumbnailimage__c field on Product2 Object.

Final code :)

Create following Apex Class and LWC component.

Modify according to your needs.

Apex Class: UploadImageCTRL

public inherited sharing class UploadImageCTRL {
    
    @AuraEnabled
    public static ContentVersion saveFile(Id idParent, String strFileName, String base64Data) {
        // Decoding base64Data
        base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
        
        // inserting file
        ContentVersion cv = new ContentVersion();
        cv.Title = strFileName;
        cv.PathOnClient = '/' + strFileName;
        cv.FirstPublishLocationId = idParent;
        cv.VersionData = EncodingUtil.base64Decode(base64Data);
        cv.IsMajorVersion = true;
        Insert cv;
        return cv;
    }

    @AuraEnabled
    public static String releatedFiles(Id idParent){
        list<id> lstConDocs = new list<id>();
        for(ContentDocumentLink cntLink : [Select Id, ContentDocumentId From ContentDocumentLink Where LinkedEntityId =:idParent]) {
            lstConDocs.add(cntLink.ContentDocumentId);
        }
        if(!lstConDocs.isEmpty()) {
            ContentDistribution cdl = new ContentDistribution();
            cdl.ContentVersionId = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE ContentDocumentId IN :lstConDocs LIMIT 1].Id;
            cdl.Name = 'PublicShare';
            insert cdl;
            Product2 p = new Product2();
            p.id = idParent;
            system.debug(idParent);
            p.thumbnailimage__c = [SELECT DistributionPublicUrl, ContentDownloadUrl FROM ContentDistribution WHERE Id = :cdl.Id LIMIT 1].ContentDownloadUrl;
            update p;
            system.debug(p.thumbnailimage__c);
            return [SELECT DistributionPublicUrl, ContentDownloadUrl FROM ContentDistribution WHERE Id = :cdl.Id LIMIT 1].ContentDownloadUrl;
        }
        else {
            return null;
        }
     
    }
    
}

LWC: thumbnailImageUpload.html

<template>
    <div class="slds-box">
        <div class="slds-box slds-grid slds-gutters">
            <div class="slds-col">

                <lightning-card title="Upload Thumbnail Image" icon-name="utility:image">
                    <div style="margin-left:4%">
                        <div>
                            <lightning-input label="" name="file uploader" onchange={handleFilesChange} type="file">
                            </lightning-input>
                        </div><br />
                        <div class="slds-text-body_small slds-text-color_error">{fileName}
                            <template if:true={showLoadingSpinner}>
                                <lightning-spinner alternative-text="Uploading......" size="medium"></lightning-spinner>
                            </template>
                        </div><br />
                        <div>
                            <template if:false={data}>
                                <lightning-button class="slds-m-top--medium" label={UploadFile} onclick={handleSave}
                                    variant="brand" disabled={isTrue}></lightning-button>
                            </template>
                            <template if:true={data}>
                                <lightning-button class="slds-m-top--medium" label="Change Image" onclick={handleSave}
                                    variant="brand" disabled={isTrue}></lightning-button>
                            </template>

                        </div>
                    </div><br /><br />
                </lightning-card>

            </div>
            <div class="slds-col">
                <lightning-card title="Thumbnail Image of the Product" icon-name="utility:image">
                    <div style="width: auto;">
                        <template if:false={data}>
                            <i class="slds-text-color_error">No image uploaded!</i>
                        </template>
                        <template if:true={data}>
                            <img src={data} width="150">
                        </template>
                    </div>
                </lightning-card>
            </div>
        </div>
    </div>
</template>

LWC: thumbnailImageUpload.js

import { LightningElement, track, api } from 'lwc';
import saveFile from '@salesforce/apex/UploadImageCTRL.saveFile';
import releatedFiles from '@salesforce/apex/UploadImageCTRL.releatedFiles';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

const columns = [
    { label: 'Title', fieldName: 'Title' }
];

export default class ThumbnailImageUpload extends LightningElement {
    @api recordId;
    @track columns = columns;
    @track data;
    @track fileName = '';
    @track UploadFile = 'Upload Image';
    @track showLoadingSpinner = false;
    @track isTrue = false;
    selectedRecords;
    filesUploaded = [];
    file;
    fileContents;
    fileReader;
    content;
    MAX_FILE_SIZE = 1500000;


    connectedCallback() {
        this.getRelatedFiles();
    }

    handleFilesChange(event) {
        if (event.target.files.length > 0) {
            this.filesUploaded = event.target.files;
            this.fileName = event.target.files[0].name;
        }
    }

    handleSave() {
        if (this.filesUploaded.length > 0) {
            this.uploadHelper();
        }
        else {
            this.fileName = 'Please select file to upload!!';
        }
    }

    uploadHelper() {
        this.file = this.filesUploaded[0];
        if (this.file.size > this.MAX_FILE_SIZE) {
            window.console.log('File Size is to long');
            return;
        }
        this.showLoadingSpinner = true;
        // create a FileReader object 
        this.fileReader = new FileReader();
        // set onload function of FileReader object  
        this.fileReader.onloadend = (() => {
            this.fileContents = this.fileReader.result;
            let base64 = 'base64,';
            this.content = this.fileContents.indexOf(base64) + base64.length;
            this.fileContents = this.fileContents.substring(this.content);

            // call the uploadProcess method 
            this.saveToFile();
        });

        this.fileReader.readAsDataURL(this.file);
    }

    // Calling apex class to insert the file
    saveToFile() {
        saveFile({ idParent: this.recordId, strFileName: this.file.name, base64Data: encodeURIComponent(this.fileContents) })
            .then(result => {
                window.console.log('result ====> ' + result);
                // refreshing the datatable
                this.getRelatedFiles();

                this.fileName = this.fileName + ' - Uploaded Successfully';
                this.UploadFile = 'File Uploaded Successfully';
                this.isTrue = true;
                this.showLoadingSpinner = false;

                // Showing Success message after file insert
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Success!!',
                        message: this.file.name + ' - Uploaded Successfully!!!',
                        variant: 'success',
                    }),
                );

            })
            .catch(error => {
                // Showing errors if any while inserting the files
                window.console.log(error);
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error while uploading File',
                        message: error.message,
                        variant: 'error',
                    }),
                );
            });
    }

    // Getting releated files of the current record
    getRelatedFiles() {
        releatedFiles({ idParent: this.recordId })
            .then(data => {
                this.data = data;
                console.log(data);
            })
            .catch(error => {
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error!!',
                        message: error.message,
                        variant: 'error',
                    }),
                );
            });
    }

    // Getting selected rows to perform any action
    getSelectedRecords(event) {
        let conDocIds;
        const selectedRows = event.detail.selectedRows;
        conDocIds = new Set();
        // Display that fieldName of the selected rows
        for (let i = 0; i < selectedRows.length; i++) {
            conDocIds.add(selectedRows[i].ContentDocumentId);
        }

        this.selectedRecords = Array.from(conDocIds).join(',');

        window.console.log('selectedRecords =====> ' + this.selectedRecords);
    }

}

LWC: thumbnailImageUpload.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Deploy to the Org.

Edit any record page and drag it to details section.

Check following image for the reference.

Image

If you have any question Ask Me

Thanks for Reading :)

Write a comment for suggestions and hit the heart icon.


2745
0

Tags: #lwc

Comments

There are no comments yet.
Your message is required.

Get notified of new posts