LWC-Lightning Datatable sorting

This is a quick post to understand how sorting is accomplished in lightning datatable (LWC).

Lightning datatable provides an onsort attribute which will allow us to implement the sorting for the elements in the table. You could implement sorting locally or via making a server call.

Local Sorting

You would generally implement this type of sorting if you know that the list of elements is going to be small and limited. For example, if you’re displaying a list of approval history records for a particular record, you know that the number of records won’t be more (assuming you have a simple approval process).

In the example below, we have created a simple component which displays the list of the contacts (firstName and lastName). When the header column is clicked the onsort handler is invoked, the field and the sort order is passed and using this information the list is sorted.

<template>
<lightning-datatable
key-field="Id"
data={results}
columns={columns}
hide-checkbox-column ="false"
show-row-number-column="true"
onsort={updateColumnSorting}
sorted-by={sortBy}
sorted-direction={sortDirection}
row-number-offset ="0" >
</lightning-datatable>
</template>

import { LightningElement,track,wire } from 'lwc';
import fetchContact from '@salesforce/apex/ContactList.fetchContactLocal';
const dataTablecolumns = [{
label: 'First Name',
fieldName: 'FirstName',
sortable : true,
type: 'text'
},
{
label : 'Last Name',
fieldName : 'LastName',
type : 'text',
sortable : true
}]
export default class ContactListLocalSort extends LightningElement {
@track results=[];
@track columns = dataTablecolumns;
@track sortBy='FirstName';
@track sortDirection='asc';
@wire(fetchContact) contactList({error, data}) {
if(data)
this.results=Object.assign([], data);
if(error)
console.log(error);
}
updateColumnSorting(event){
let fieldName = event.detail.fieldName;
let sortDirection = event.detail.sortDirection;
//assign the values
this.sortBy = fieldName;
this.sortDirection = sortDirection;
//call the custom sort method.
this.sortData(fieldName, sortDirection);
}
//This sorting logic here is very simple. This will be useful only for text or number field.
// You will need to implement custom logic for handling different types of field.
sortData(fieldName, sortDirection) {
let sortResult = Object.assign([], this.results);
this.results = sortResult.sort(function(a,b){
if(a[fieldName] < b[fieldName])
return sortDirection === 'asc' ? 1 : 1;
else if(a[fieldName] > b[fieldName])
return sortDirection === 'asc' ? 1 : 1;
else
return 0;
})
}
}

https://gist.github.com/jungleeforce/7ffb0e94bf0d5641d162f6295ac9df9f.js

Sorting via server call

As you would have guessed this would be useful when you have a huge list and you are displaying a small chunk of the total records.

The major advantage of this method is that you need not implement any custom logic at all. The sorting will be completely handled by the SOQL. Another thing to note here is that you will have to disable the data-table so that the user’s do not click on the header in the time the server call is being executed.

<template>
<lightning-datatable
key-field="Id"
data={results}
columns={columns}
hide-checkbox-column ="false"
show-row-number-column="true"
onsort={updateColumnSorting}
sorted-by={sortBy}
sorted-direction={sortDirection}
row-number-offset ="0" >
</lightning-datatable>
</template>

import { LightningElement,track,wire } from 'lwc';
import fetchContact from '@salesforce/apex/ContactList.fetchContact';
const dataTablecolumns = [{
label: 'First Name',
fieldName: 'FirstName',
sortable : true,
type: 'text'
},
{
label : 'Last Name',
fieldName : 'LastName',
type : 'text',
sortable : true
}]
export default class ContactListServerSort extends LightningElement {
@track results=[];
@track columns = dataTablecolumns;
@track sortBy='FirstName';
@track sortDirection='asc';
//since we have used the dynamic wiring,
//the list is automatically refreshed when the sort direction or order changes.
@wire(fetchContact,{field : '$sortBy',sortOrder : '$sortDirection'}) contactList({error, data}) {
if(data)
this.results=Object.assign([], data);
if(error)
console.log(error);
}
updateColumnSorting(event){
let fieldName = event.detail.fieldName;
let sortDirection = event.detail.sortDirection;
//assign the values. This will trigger the wire method to reload.
this.sortBy = fieldName;
this.sortDirection = sortDirection;
}
}

Apex class

public with sharing class ContactList {
@AuraEnabled (Cacheable=true)
public static List<Contact> fetchContactLocal(){
return [SELECT Id, FirstName, LastName
FROM CONTACT Order By FirstName ASC];
}
@AuraEnabled (Cacheable=true)
public static List<Contact> fetchContact(String field, String sortOrder){
return Database.query('SELECT Id, FirstName, LastName FROM Contact ORDER BY '+field+' '+sortOrder);
}
}

view raw

ContactList.cls

hosted with ❤ by GitHub

2 thoughts on “LWC-Lightning Datatable sorting”

  1. Thank you for the nice post!
    I want what is reason behind when you says if you have small amount amount of data then use ‘Local Sorting ‘. Why we can’t use local sorting for large amount of data ?

    1. When u do local sorting the data is stored in-memory and that consumes lot of CPU resources. Now if you were to start sorting, paginating the records locally ( in the page) you will see performance issues when u load huge amount of data, says >10k ( again this depends on the machine’s configuration, how many tabs are already open and how much of the machine’s resources are utilized etc).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s