Hello everyone, Today i will post a ligthning datatable example that support lazy/infinite loading in lightning web component(lwc). When you have to show large amount of data in datatable but you don't want to load all data at a time, this may hit salesforce govenor limit. so here lazy/infinite loading will help you to achieve this requirement. Let's see an example
Lazy loading in datatable in lightning web component
In lazy/infinite loading, some amount of data are shown at a time to a user and when the user scrolled down the next log of fresh records are fetched and appended to existing records and displayed on UI.
In below example, I have fetched 20 records of account and bind in datatable. When i scrolled down the next 20 records are fetched and appended to UI.
LazyLoadingHandler.apxc
public class LazyLoadingHandler {LazyLoading.html
@AuraEnabled
public static List<Account> getAccountRecords(Integer offSetCount) {
return [SELECT Id, Name, AccountNumber, Phone, CreatedDate FROM Account order by Name asc LIMIT 20 OFFSET :offSetCount];
}
}
<template>LazyLoading.js
<lightning-card>
<div class="slds-var-p-around_small">
<div>
<span
class="slds-form-element__label slds-text-title_bold slds-align_absolute-center">
<u>Infinite/Lazy Loading Example</u></span>
</div>
<div>
<span class="slds-form-element__label slds-text-title_bold">
Total Records: {totalNumberOfRows}</span>
</div>
<div>
<span class="slds-form-element__label slds-text-title_bold">
Displayed Records: {data.length}</span>
</div>
<div class="slds-box" style="height: 400px;">
<lightning-datatable key-field="Id" data={data} columns={columns} load-more-offset="20"
onloadmore={handleLoadMore} enable-infinite-loading hide-checkbox-column show-row-number-column>
</lightning-datatable>
</div>
{loadMoreStatus}
</div>
</lightning-card>
</template>
import { LightningElement } from 'lwc';LazyLoading.js-meta.xml
import getAccountRecords from '@salesforce/apex/LazyLoadingHandler.getAccountRecords';
const columns = [
{
label: 'Account Name', fieldName: 'linkAccount', type: 'url',
typeAttributes: {
label: { fieldName: 'Name' },
target: '_blank'
}
},
{ label: 'Account Number', fieldName: 'AccountNumber', type: 'text' },
{ label: 'Phone', fieldName: 'Phone', type: 'text' },
{ label: 'Created Date', fieldName: 'CreatedDate', type: 'text' }
];
export default class LazyLoading extends LightningElement {
columns = columns;
data = [];
error;
totalNumberOfRows = 100; // stop the infinite load after this threshold count
offSetCount = 0;
loadMoreStatus;
targetDatatable; // capture the loadmore event to fetch data and stop infinite loading
connectedCallback() {
//Get initial chunk of data with offset set at 0
this.getRecords();
}
getRecords() {
getAccountRecords({ offSetCount: this.offSetCount })
.then(result => {
// Returned result if from sobject and can't be extended so objectifying the result to make it extensible
result = JSON.parse(JSON.stringify(result));
result.forEach(record => {
record.linkAccount = '/' + record.Id;
});
this.data = [...this.data, ...result];
this.error = undefined;
this.loadMoreStatus = '';
if (this.targetDatatable && this.data.length >= this.totalNumberOfRows) {
//stop Infinite Loading when threshold is reached
this.targetDatatable.enableInfiniteLoading = false;
//Display "No more data to load" when threshold is reached
this.loadMoreStatus = 'No more data to load';
}
//Disable a spinner to signal that data has been loaded
if (this.targetDatatable) this.targetDatatable.isLoading = false;
})
.catch(error => {
this.error = error;
this.data = undefined;
console.log('error : ' + JSON.stringify(this.error));
});
}
// Event to handle onloadmore on lightning datatable markup
handleLoadMore(event) {
event.preventDefault();
// increase the offset count by 20 on every loadmore event
this.offSetCount = this.offSetCount + 20;
//Display a spinner to signal that data is being loaded
event.target.isLoading = true;
//Set the onloadmore event taraget to make it visible to imperative call response to apex.
this.targetDatatable = event.target;
//Display "Loading" when more data is being loaded
this.loadMoreStatus = 'Loading';
// Get new set of records and append to this.data
this.getRecords();
}
}
<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Output:
Hope you like this post, for any feedback or suggestions please feel free to comment. I would appreciate your feedback and suggestions.
Happy Coding
Thank you.
3 Comments
Does this work if there are over 2000 records returned ?
ReplyDeletesure, but if datatable support over 2000 records, without pagination.
DeleteDoes this work upto 50k records
ReplyDeletePost a Comment