How To Implement Infinity Or Lazy Loading In Salesforce Lightning DataTable
Hi guys welcome back, Today in this post we are going to learn how we can implement infinity or lazy loading in salesforce ‘lightning:datatable’ lightning component using offset feature.
From developer console >> file >> new >> Apex Class
Apex Class : AccountTableController.apxc
/* * Date : 3/4/2019 * API : 45 * Source : sfdcMonkey.com */ public class AccountTableController { //To return initial account records @AuraEnabled public static AccountWrapper getAccountRecords(Integer initialRows){ AccountWrapper accountWrapper= new AccountWrapper(); try{ accountWrapper.accountsList = [SELECT ID,Name,Rating,AccountSource FROM Account ORDER BY Name ASC LIMIT :initialRows OFFSET 0]; accountWrapper.totalRecords = [SELECT COUNT() FROM Account]; accountWrapper.message = 'Account records are loaded'; accountWrapper.success = true; } catch(Exception e){ accountWrapper.message = e.getMessage(); accountWrapper.success = false; } return accountWrapper; } //To return additional records based on offset @AuraEnabled public static List<Account> loadAccountRecords(Integer rowLimit,Integer rowOffset){ return [SELECT ID,Name,Rating,AccountSource FROM Account ORDER BY Name ASC LIMIT :rowLimit OFFSET :rowOffset]; } // wrapper class public class AccountWrapper{ @AuraEnabled public Integer totalRecords = 0; @AuraEnabled public List<Account> accountsList = new List<Account>(); @AuraEnabled public String message; @AuraEnabled public Boolean success; } }
From developer console >> file >> new >> Lightning Component
Lightning Component : infinityLoading.cmp
<!-- Source : sfdcmonkey.com Date : 3/4/2019 API : 45.0 --> <aura:component controller="AccountTableController" implements="flexiPage:availableForAllPageTypes"> <aura:handler name="init" value="{!this}" action="{!c.onInit}"/> <!--Aura Attributes START--> <aura:attribute name="accountColums" type="List"/> <aura:attribute name="accountData" type="Object"/> <aura:attribute name="enableInfiniteLoading" type="Boolean" default="true"/> <aura:attribute name="initialRows" type="Integer" default="10"/> <aura:attribute name="currentCount" type="Integer" default="10"/> <aura:attribute name="totalRows" type="Integer" default="0"/> <aura:attribute name="loadOffset" type="Integer" default="1"/><!--Set when to trigger loading of more rows--> <!--Aura Attributes END--> <div class="slds-page-header" role="banner"> <span class="slds-page-header__title">Accounts List</span> </div> <!--Lightning data table markup--> <div style="height:250px"> <lightning:datatable aura:id="dataTableID" keyField="Id" hideCheckboxColumn="true" columns="{!v.accountColums}" data="{!v.accountData}" enableInfiniteLoading="{!v.enableInfiniteLoading}" loadMoreOffset="{!v.loadOffset}" onloadmore="{!c.handleLoadMore}"/> </div> </aura:component>
JavaScript Controller : infinityLoadingController.js
/* * Date : 3/4/2019 * API : 45 * Source : sfdcMonkey.com */ ({ onInit : function(component,event,helper){ //Setting up colum information component.set("v.accountColums", [ { label : 'Name', fieldName : 'accountName', type : 'url', typeAttributes:{label:{fieldName:'Name'},target:'_blank'} }, { label : 'Account Source', fieldName : 'AccountSource', type : 'text', }, { label : 'Rating', fieldName : 'Rating', type : 'text', } ]); // Call helper to set the data for account table helper.getData(component); }, handleLoadMore : function(component,event,helper){ if(!(component.get("v.currentCount") >= component.get("v.totalRows"))){ //To display the spinner event.getSource().set("v.isLoading", true); //To handle data returned from Promise function helper.loadData(component).then(function(data){ var currentData = component.get("v.accountData"); var newData = currentData.concat(data); component.set("v.accountData", newData); //To hide the spinner event.getSource().set("v.isLoading", false); }); } else{ //To stop loading more rows component.set("v.enableInfiniteLoading",false); event.getSource().set("v.isLoading", false); var toastReference = $A.get("e.force:showToast"); toastReference.setParams({ "type":"Success", "title":"Success", "message":"All Account records are loaded", "mode":"dismissible" }); toastReference.fire(); } }, })
JavaScript Helper: infinityLoadingHelper.js
/* * Date : 3/4/2019 * API : 45 * Source : sfdcMonkey.com */ ({ getData : function(component){ // call apex class method var action = component.get("c.getAccountRecords"); action.setParams({ "initialRows" : component.get("v.initialRows") //how many rows to load during initialization }); action.setCallback(this,function(response){ var state = response.getState(); var toastReference = $A.get("e.force:showToast"); if(state == "SUCCESS"){ var accountWrapper = response.getReturnValue(); if(accountWrapper.success){ // set total rows count from response wrapper component.set("v.totalRows",accountWrapper.totalRecords); var accountList = accountWrapper.accountsList; // play a for each loop on list of account and set Account URL in custom 'accountName' field accountList.forEach(function(account){ account.accountName = '/'+account.Id; }); // set the updated response on accountData aura attribute component.set("v.accountData",accountList); // display a success message toastReference.setParams({ "type" : "Success", "title" : "Success", "message" : accountWrapper.message, "mode" : "dismissible" }); toastReference.fire(); } else{ // if any server side error, display error msg from response toastReference.setParams({ "type" : "Error", "title" : "Error", "message" : accountWrapper.message, "mode" : "sticky" }); toastReference.fire(); } } else{ // if any callback error, display error msg toastReference.setParams({ "type" : "Error", "title" : "Error", "message" : 'An error occurred during Initialization '+state, "mode" : "sticky" }); toastReference.fire(); } }); $A.enqueueAction(action); }, loadData : function(component){ return new Promise($A.getCallback(function(resolve){ var limit = component.get("v.initialRows"); var offset = component.get("v.currentCount"); var totalRows = component.get("v.totalRows"); if(limit + offset > totalRows){ limit = totalRows - offset; } var action = component.get("c.loadAccountRecords"); action.setParams({ "rowLimit" : limit, "rowOffset" : offset }); action.setCallback(this,function(response){ var state = response.getState(); var newData = response.getReturnValue(); // play a for each loop on list of new accounts and set Account URL in custom 'accountName' field newData.forEach(function(account){ account.accountName = '/'+account.Id; }); resolve(newData); var currentCount = component.get("v.currentCount"); currentCount += component.get("v.initialRows"); // set the current count with number of records loaded component.set("v.currentCount",currentCount); }); $A.enqueueAction(action); })); } })
Check code comments.
Infinity Loading Component Output :
Related Resources :
Other popular Post :
- Override Standard Buttons With Lightning Component – Lightning Experience
- Display Colorful Values Based on Picklist Value in Lightning Component Data Table
- How to use Map in lightning Component
- Use SVG in Salesforce Lightning Component ?
- Quick Send Email Lightning Component
Like our facebook page for new post updates. & Don’t forget to bookmark this site for your future reference.
if you have any suggestions or issue with it, you can post in comment box.
Happy Learning
About The contributor:
I have 3.5 years of experience and working in lightning for the past 1 year. I am working as a developer in Deloitte.
Skills : Apex ,lightning , visualforce,sales cloud,JavaScript,Einstein analytics
Post By Kiran :
2 comments
This is giving error as
Error in $A.getCallback() [Cannot read property ‘setParams’ of undefined] Callback failed: apex://AccountTableController/ACTION$getAccountRecords Failing descriptor: {c:infinityLoading}
Please help.
Thank you!
I am getting following error,Please help.
Error in $A.getCallback() [Cannot read property ‘setParams’ of undefined] Callback failed: apex://AccountTableController/ACTION$getAccountRecords Failing descriptor: {c:infinityLoading}