Sunday, June 7, 2020

Lazy Loading implementation in Lightning Web Components

    To load more data in Salesforce lightning in tabular form, will cause performance issue to load data on page or application get slow down, if there is no pagination applied on table. To overcome from this problem, we can use Lightning:Datatable with infinite loading data with help of specific Offset.
  • Use lightning:datatable in Lightning Web Component
  • enable-infinite-loading attribute at client side
  • Data should retrieve only when requested 
  • When user scroll down the table to see more records in table, application should render next coming records.
  • Records to be retrieved in chunks.
To get it done as practical please follow below example.

Example: Grab all existing Accounts in a table with using lazy loading.

accountsList.html
<template>
<div class="slds-box slds-theme_default">
<lightning-card>
<h3 slot="title" class="slds-text-title_bold">
<lightning-icon icon-name="standard:client" size="small"></lightning-icon>
<span class="slds-m-left_small">Key Accounts</span>
</h3>

<lightning-layout>
<lightning-layout-item size="12">
<div style="height: 15rem">
<lightning-datatable
key-field="id"
data={accounts}
columns={columns}
is-loading={tableLoadingState}
enable-infinite-loading
onloadmore={loadMoreData}>
</lightning-datatable>
</div>
{loadMoreStatus}
</lightning-layout-item>
</lightning-layout>
</lightning-card>
</div>
</template>


accountsList.js
import { LightningElement, api, track, wire } from 'lwc';
import { refreshApex } from '@salesforce/apex';
import getAccountList from '@salesforce/apex/MatrixPricingNegotiationController.getAccountList';

const columns = [
{ label: "Name", fieldName: "Name" },
{ label: "Client Code", fieldName: "Client_Code__c" },
{ label: "Status", fieldName: "Status__c"},
{ label: "Created Date", fieldName: "CreatedDate", type: "date" }
];

export default class FetchAccounts extends LightningElement {
@api recordId = '';
@api queryOffset = 0;
@api loadMoreStatus;
error;
columns = columns;
totalAccounts;
@track accounts = [];
@track tableLoadingState = "false";
@wire(getAccountList, {queryOffset: '$queryOffset'})
wiredContacts({data, error}){
console.log('data :::', data);
if(data || data == null){

console.log('hello');
if(data == null){

this.loadMoreStatus = 'No more records to show!'
} else {
if(this.accounts) {
this.accounts = this.accounts.concat(data)
} else {
this.accounts = data;
}
this.error = undefined;
this.loadMoreStatus = '';
}
this.tableLoadingState = false;
}
else if (error) {
this.error = error;
this.accounts = undefined;
this.tableLoadingState = false;
}
}

loadMoreData(event) {
console.log('event :::', JSON.stringify(event));
this.tableLoadingState = true;
event.target.isLoading = true;
if(this.accounts && this.loadMoreStatus == '') {
this.queryOffset += 10;
refreshApex(this.wiredContacts);
} else {
this.tableLoadingState = false;
}
event.target.isLoading = false;
}
}
AccountsListController.apex
public without sharing class AccountListController {
    public static integer totalAccounts = [SELECT count() FROM Account];
    @AuraEnabled(cacheable=true)
public static List<Account> getAccountList(Integer queryOffset) {

if(queryOffset <= totalAccounts) {

return [SELECT Id, Name, Client_Code__c, CreatedDate, Status__c                     FROM Account Order By CreatedDate Limit 10 OFFSET:queryOffset];
} else {
return null;
}
}
}

Demo:
Lazy Loading




No comments:

Post a Comment