You need to sign in to do that
Don't have an account?

Lightning:datatable Infinite Scroll
Hello,
So i am trying to implement the "Infinite Scrolling to Load More Rows" in a datatable. I am trying to implement the example found at https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_datatable.htm. However there is a helper method called in the JS Controller called "fetchData" that is not there and i cant for the life of me make it myself. I have tried everything. Any help would be greatly appreciated.
Please see code below.
Component:
<aura:component controller="ContactController" implements="force:appHostable,flexipage:availableForAllPageTypes" access="global">
<aura:attribute name="mydata" type="Object" />
<aura:attribute name="mycolumns" type="List"/>
<aura:attribute name="isLoading" type="Boolean" default="true"/>
<aura:attribute name="contactId" type="Id" />
<aura:attribute name="sortedBy" type="String" />
<aura:attribute name="sortedDirection" type="String" />
<aura:attribute name="enableInfiniteLoading" type="Boolean" default="true"/>
<aura:attribute name="initialRows" type="Integer" default="10"/>
<aura:attribute name="rowsToLoad" type="Integer" default="50"/>
<aura:attribute name="totalNumberOfRows" type="Integer" default="300"/>
<aura:attribute name="loadMoreStatus" type="String" default=""/>
<aura:handler name="init" value="{! this }" action="{! c.init }"/>
<div style="height: 500px">
<lightning:datatable data="{! v.mydata}"
columns="{! v.mycolumns }"
keyField="id"
onsort="{!c.updateColumnSorting}"
sortedBy="{!v.sortedBy}"
sortedDirection="{!v.sortedDirection}"
enableInfiniteLoading="true"
onloadmore="{! c.loadMoreData }"/>
</div>
{! v.loadMoreStatus}
</aura:component>
JS Controller:
({
init: function (cmp, event, helper) {
var actions = [
{ label: 'Show details', name: 'show_details' },
{ label: 'Delete', name: 'delete' }
];
cmp.set('v.mycolumns', [
// Other column data here
{ type: 'action', typeAttributes: { rowActions: actions } }
]);
cmp.set('v.mycolumns', [
{label: 'Contact Name', fieldName: 'Name', type: 'string', sortable: 'true'},
{label: 'Phone', fieldName: 'Phone', type: 'phone', sortable: 'true'},
{label: 'Email', fieldName: 'Email', type: 'email', sortable: 'true'}
]);
helper.getData(cmp);
},
getSelectedName: function (cmp, event) {
var selectedRows = event.getParam('selectedRows');
// Display that fieldName of the selected rows
for (var i = 0; i < selectedRows.length; i++){
alert("You selected: " + selectedRows[i].Name);
}
},
handleRowAction: function (cmp, event, helper) {
var action = event.getParam('action');
var row = event.getParam('row');
switch (action.name) {
case 'show_details':
alert('Showing Details: ' + JSON.stringify(row));
cmp.set('v.contactId', row.Id);
alert(cmp.get('v.contactId'));
$A.util.removeClass(cmp.find("childDiv"),'toggle');
$A.util.addClass(cmp.find("listDiv"),'toggle');
var attribute1 = cmp.get('v.contactId');
var childComponent = cmp.find('child');
childComponent.reInit(attribute1);
break;
case 'delete':
var rows = cmp.get('v.mydata');
var rowIndex = rows.indexOf(row);
rows.splice(rowIndex, 1);
cmp.set('v.mydata', rows);
break;
}
},
//Client-side controller called by the onsort event handler
updateColumnSorting: function (cmp, event, helper) {
var fieldName = event.getParam('fieldName');
var sortDirection = event.getParam('sortDirection');
// assign the latest attribute with the sorted column fieldName and sorted direction
cmp.set("v.sortedBy", fieldName);
cmp.set("v.sortedDirection", sortDirection);
helper.sortData(cmp, fieldName, sortDirection);
},
loadMoreData: function (cmp, event, helper) {
//Display a spinner to signal that data is being loaded
event.getSource().set("v.isLoading", true);
//Display "Loading" when more data is being loaded
cmp.set('v.loadMoreStatus', 'Loading');
helper.fetchData(cmp, cmp.get('v.rowsToLoad'))
.then($A.getCallback(function (data) {
if (cmp.get('v.mydata').length >= cmp.get('v.totalNumberOfRows')) {
cmp.set('v.enableInfiniteLoading', false);
cmp.set('v.loadMoreStatus', 'No more data to load');
} else {
var currentData = cmp.get('v.mydata');
//Appends new data to the end of the table
var newData = currentData.concat(data);
cmp.set('v.mydata', newData);
cmp.set('v.loadMoreStatus', '');
}
event.getSource().set("v.isLoading", false);
}));
}
})
HELPER
This is where i need the help to come up with a helper method that is referenced in the JS controller. THANK YOU!
So i am trying to implement the "Infinite Scrolling to Load More Rows" in a datatable. I am trying to implement the example found at https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_datatable.htm. However there is a helper method called in the JS Controller called "fetchData" that is not there and i cant for the life of me make it myself. I have tried everything. Any help would be greatly appreciated.
Please see code below.
Component:
<aura:component controller="ContactController" implements="force:appHostable,flexipage:availableForAllPageTypes" access="global">
<aura:attribute name="mydata" type="Object" />
<aura:attribute name="mycolumns" type="List"/>
<aura:attribute name="isLoading" type="Boolean" default="true"/>
<aura:attribute name="contactId" type="Id" />
<aura:attribute name="sortedBy" type="String" />
<aura:attribute name="sortedDirection" type="String" />
<aura:attribute name="enableInfiniteLoading" type="Boolean" default="true"/>
<aura:attribute name="initialRows" type="Integer" default="10"/>
<aura:attribute name="rowsToLoad" type="Integer" default="50"/>
<aura:attribute name="totalNumberOfRows" type="Integer" default="300"/>
<aura:attribute name="loadMoreStatus" type="String" default=""/>
<aura:handler name="init" value="{! this }" action="{! c.init }"/>
<div style="height: 500px">
<lightning:datatable data="{! v.mydata}"
columns="{! v.mycolumns }"
keyField="id"
onsort="{!c.updateColumnSorting}"
sortedBy="{!v.sortedBy}"
sortedDirection="{!v.sortedDirection}"
enableInfiniteLoading="true"
onloadmore="{! c.loadMoreData }"/>
</div>
{! v.loadMoreStatus}
</aura:component>
JS Controller:
({
init: function (cmp, event, helper) {
var actions = [
{ label: 'Show details', name: 'show_details' },
{ label: 'Delete', name: 'delete' }
];
cmp.set('v.mycolumns', [
// Other column data here
{ type: 'action', typeAttributes: { rowActions: actions } }
]);
cmp.set('v.mycolumns', [
{label: 'Contact Name', fieldName: 'Name', type: 'string', sortable: 'true'},
{label: 'Phone', fieldName: 'Phone', type: 'phone', sortable: 'true'},
{label: 'Email', fieldName: 'Email', type: 'email', sortable: 'true'}
]);
helper.getData(cmp);
},
getSelectedName: function (cmp, event) {
var selectedRows = event.getParam('selectedRows');
// Display that fieldName of the selected rows
for (var i = 0; i < selectedRows.length; i++){
alert("You selected: " + selectedRows[i].Name);
}
},
handleRowAction: function (cmp, event, helper) {
var action = event.getParam('action');
var row = event.getParam('row');
switch (action.name) {
case 'show_details':
alert('Showing Details: ' + JSON.stringify(row));
cmp.set('v.contactId', row.Id);
alert(cmp.get('v.contactId'));
$A.util.removeClass(cmp.find("childDiv"),'toggle');
$A.util.addClass(cmp.find("listDiv"),'toggle');
var attribute1 = cmp.get('v.contactId');
var childComponent = cmp.find('child');
childComponent.reInit(attribute1);
break;
case 'delete':
var rows = cmp.get('v.mydata');
var rowIndex = rows.indexOf(row);
rows.splice(rowIndex, 1);
cmp.set('v.mydata', rows);
break;
}
},
//Client-side controller called by the onsort event handler
updateColumnSorting: function (cmp, event, helper) {
var fieldName = event.getParam('fieldName');
var sortDirection = event.getParam('sortDirection');
// assign the latest attribute with the sorted column fieldName and sorted direction
cmp.set("v.sortedBy", fieldName);
cmp.set("v.sortedDirection", sortDirection);
helper.sortData(cmp, fieldName, sortDirection);
},
loadMoreData: function (cmp, event, helper) {
//Display a spinner to signal that data is being loaded
event.getSource().set("v.isLoading", true);
//Display "Loading" when more data is being loaded
cmp.set('v.loadMoreStatus', 'Loading');
helper.fetchData(cmp, cmp.get('v.rowsToLoad'))
.then($A.getCallback(function (data) {
if (cmp.get('v.mydata').length >= cmp.get('v.totalNumberOfRows')) {
cmp.set('v.enableInfiniteLoading', false);
cmp.set('v.loadMoreStatus', 'No more data to load');
} else {
var currentData = cmp.get('v.mydata');
//Appends new data to the end of the table
var newData = currentData.concat(data);
cmp.set('v.mydata', newData);
cmp.set('v.loadMoreStatus', '');
}
event.getSource().set("v.isLoading", false);
}));
}
})
HELPER
This is where i need the help to come up with a helper method that is referenced in the JS controller. THANK YOU!
All Answers
-The loadMoreOffset attribute needs to be set in the component, correct?
-when I run this, using console logs, I can see that there is an infinite loop where the code is constantly calling "loadmoredata", even though the total number of records (2) is less than the rows to load limit (10). It is constantly trying to load more data, and I cannot figure out why.
This is because you are never disabling Infinte scrolling.
Here's change to fix this refering the best answer.
For lightning:datatable in component replace enableInfiniteLoading="true" to enableInfiniteLoading="{! v.enableInfiniteLoading}"
Altough i have one observation : performin header Action : It loads the filtered record at the last line cmp.set('v.data', filteredRows);
but it also executes the infite loading causing other ten records to populate. SO using cmp.set('v.enableInfiniteLoading', false);
befoe the last line will solve the issue.
ANother issu eis once i have filtered on "Completed" i need to refresh the page to filter with another.
https://newstechnologystuff.com/2019/01/01/lightning-datatable-lazy-loading-with-inline-editing-and-actions/
https://inevitableyogendra.blogspot.com/2021/05/infinite-loading-in-lightning-datatable.html (https://inevitableyogendra.blogspot.com/2021/05/infinite-loading-in-lightning-datatable.html" target="_blank)
You will get many view and approaches to implement the solution.