In this post we will talk about How to implement Infinity or lazy loading in Lightning Web Component using Lightning Datatable. Lazy loading helps you to load the data only when it is required. Infinite scrolling (enable-infinite-loading) enables you to load a subset of data and then load more data when users scroll to the end of the table.
In this post we will learn about lightning datatable attributes enable-infinite-loading and load more offset.
Lets see how we can implement the same.
LazyLoadingController
public with sharing class LazyLoadingController {
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts(Integer limitSize, Integer offset){
List<Account> accountList = [SELECT Id,Name,Rating
FROM Account
ORDER BY CreatedDate
LIMIT :limitSize
OFFSET :offset
];
return accountList;
}
}
We will call same apex class from lightning web component.
Create lightning web component in your sandbox or developer org. If you new please check this post how to create lightning web component in non-scratch org.
lazyLoadingLWCDemo.html
lazyLoadingLWCDemo.js
import { LightningElement, track, wire } from 'lwc';
import getAccounts from '@salesforce/apex/LazyLoadingController.getAccounts';
const columns = [
{ label: 'Id', fieldName: 'Id', type: 'text' },
{ label: 'Name', fieldName: 'Name', type: 'text'},
{ label: 'Rating', fieldName: 'Rating', type: 'text'}
];
export default class LazyLoadingLWCDemo extends LightningElement {
accounts=[];
error;
columns = columns;
rowLimit =25;
rowOffSet=0;
connectedCallback() {
this.loadData();
}
loadData(){
return getAccounts({ limitSize: this.rowLimit , offset : this.rowOffSet })
.then(result => {
let updatedRecords = [...this.accounts, ...result];
this.accounts = updatedRecords;
this.error = undefined;
})
.catch(error => {
this.error = error;
this.accounts = undefined;
});
}
loadMoreData(event) {
const currentRecord = this.accounts;
const { target } = event;
target.isLoading = true;
this.rowOffSet = this.rowOffSet + this.rowLimit;
this.loadData()
.then(()=> {
target.isLoading = false;
});
}
}
We create connectedCallback function to load the initial data and then we are useing loadmoreData function to load more record from Apex base on offset. The onloadmore event handler retrieves more data when you scroll to the bottom of the table until there are no more data to load. To display a spinner while data is being loaded, set the isLoading property to true
lazyLoadingLWCDemo.js-meta.xml
Reference blog
Further Learning
Please share your feedback and let me know if this code can be improve.
In this post we will learn about lightning datatable attributes enable-infinite-loading and load more offset.
- enable-infinite-loading : You can load a subset of data and then display more
when users scroll to the end of the table. Use with the onloadmore event handler to retrieve more data - load-more-offset : Determines when to trigger infinite loading based on how many pixels the table's scroll position is from the bottom of the table. The default is 20
- onloadmore : The action triggered when infinite loading loads more data
Lets see how we can implement the same.
Step 1) Apex Class with offSet
LazyLoadingController
public with sharing class LazyLoadingController {
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts(Integer limitSize, Integer offset){
List<Account> accountList = [SELECT Id,Name,Rating
FROM Account
ORDER BY CreatedDate
LIMIT :limitSize
OFFSET :offset
];
return accountList;
}
}
Step 2) Lightning web component with Datatable
Create lightning web component in your sandbox or developer org. If you new please check this post how to create lightning web component in non-scratch org.
lazyLoadingLWCDemo.html
<template>
<div style="height:500px">
<lightning-datatable key-field="Id"
data={accounts}
columns={columns}
enable-infinite-loading
onloadmore={loadMoreData}
hide-checkbox-column="true"
show-row-number-column="true">
</lightning-datatable>
</div>
</template>
To enable infinite scrolling, specify enable-infinite-loading and provide an event handler using onloadmore.<div style="height:500px">
<lightning-datatable key-field="Id"
data={accounts}
columns={columns}
enable-infinite-loading
onloadmore={loadMoreData}
hide-checkbox-column="true"
show-row-number-column="true">
</lightning-datatable>
</div>
</template>
lazyLoadingLWCDemo.js
import { LightningElement, track, wire } from 'lwc';
import getAccounts from '@salesforce/apex/LazyLoadingController.getAccounts';
const columns = [
{ label: 'Id', fieldName: 'Id', type: 'text' },
{ label: 'Name', fieldName: 'Name', type: 'text'},
{ label: 'Rating', fieldName: 'Rating', type: 'text'}
];
export default class LazyLoadingLWCDemo extends LightningElement {
accounts=[];
error;
columns = columns;
rowLimit =25;
rowOffSet=0;
connectedCallback() {
this.loadData();
}
loadData(){
return getAccounts({ limitSize: this.rowLimit , offset : this.rowOffSet })
.then(result => {
let updatedRecords = [...this.accounts, ...result];
this.accounts = updatedRecords;
this.error = undefined;
})
.catch(error => {
this.error = error;
this.accounts = undefined;
});
}
loadMoreData(event) {
const currentRecord = this.accounts;
const { target } = event;
target.isLoading = true;
this.rowOffSet = this.rowOffSet + this.rowLimit;
this.loadData()
.then(()=> {
target.isLoading = false;
});
}
}
lazyLoadingLWCDemo.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>48.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>48.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Reference blog
Further Learning
- Lightning datatable In Lightning Web Components
- Lightning Datatable Sorting in Lightning Web Components
Please share your feedback and let me know if this code can be improve.
Nice one.
ReplyDeleteJust wanted to check if this approach will still work if records are more than 2k and offset reaches 2000?
Thanks
it not work
DeleteconnectedCallback() --when is this method can be fired first??
DeleteIn Salesforce offset has maximum value 2000. How could show 5lakh data using lazy load
ReplyDeleteHi Amit,
ReplyDeleteI m using lightning out(aura dependency app and vf page) to embed my lwc in the standard case detail page. I have implemented the above approach in the lightning web component but it does seem to work.
However the
The 2000 offset limit is a major problem at this point. We have a table that is 10k plus and basically have to pull back and manage in javascript as not being able to specify an offset larger then 2000.
ReplyDeleteI had this issue for the same example if i am using a datatable with check box. when ever the rowsize is less than row limit the checkbox was getting unchecked. The solution for this workaround is you can use a if condition with no of records with rowlimit.
ReplyDeleteWhy the currentRecord assignment in loadMoreData? It is not used anywhere else in the code.
ReplyDeleteCan you please add the sort functionality to any of the columns
ReplyDelete