[SalesForce] Lightning Web Component – Sort table columns

I'm trying to implement the sorting functionality on a lightning datatable in a lwc. The table display a list of Opportunity. But my problem is when I click on a column for sorting data, I am getting the following error

enter image description here

Here is the opportunityList.html:

<template>
      <lightning-datatable key-field="Id" 
                           data={opportunities} 
                           columns={columns}  
                           onsort={updateColumnSorting} 
                           sorted-by={sortedBy} 
                           sorted-direction={sortedDirection}>
      </lightning-datatable>

here is the opportunityList.js:

import { LightningElement ,wire,track} from 'lwc';
import getAllOpps from '@salesforce/apex/GetAllOpportunities.getAllOpps';

export default class OpportunityList extends LightningElement {

 @track columns = [
        {
            label: 'Opportunity name',
            fieldName: 'Name',
            type: 'text',
            sortable: true
        },
        {
            label: 'Stage Name',
            fieldName: 'StageName',
            type: 'text',
            sortable: true
        },
        {
            label: 'Close date',
            fieldName: 'CloseDate',
            type: 'date',
            sortable: true
        }

    ];

    @track error;
    @track opportunities = [];
    @track sortedBy;
    @track sortedDirection = 'asc';

    @wire(getAllOpps)
    wiredOpps({error,data}) {
        if (data) {
            this.opportunities = data;
        } else if (error) {
            this.error = error;
        }
    }

    sortData(fieldName, sortDirection){
        var data = this.opportunities;
        //function to return the value stored in the field
        var key =(a) => a[fieldName]; 
        var reverse = sortDirection === 'asc' ? 1: -1;
        data.sort((a,b) => {
            let valueA = key(a) ? key(a).toLowerCase() : '';
            let valueB = key(b) ? key(b).toLowerCase() : '';
            return reverse * ((valueA > valueB) - (valueB > valueA));
        });

        //set sorted data to opportunities attribute
        this.opportunities = data;
    }

    updateColumnSorting(event){
        this.sortedBy = event.detail.fieldName;
        this.sortedDirection = event.detail.sortDirection;
        this.sortData(this.sortedBy,this.sortedDirection);       
    }

}

Please, can someone tell me what's wrong in the sortData method?

PS: When I comment this following part of the sortData method

/*data.sort((a,b) => {
    let valueA = key(a) ? key(a).toLowerCase() : '';
    let valueB = key(b) ? key(b).toLowerCase() : '';
    return reverse * ((valueA > valueB) - (valueB > valueA));
});*/

I don't get an error when I'm clicking on a column.

Thanks in advance.

Best Answer

There is problem at below line in sortData function.

 var data = this.opportunities;

If you write log for this.opportunities.You will get empty array.

enter image description here Change above mentioned line with below one will resolve the issue.

var data = JSON.parse(JSON.stringify(this.opportunities));

So sortData function will be

sortData(fieldName, sortDirection){
        var data = JSON.parse(JSON.stringify(this.opportunities));
        //function to return the value stored in the field
        var key =(a) => a[fieldName]; 
        var reverse = sortDirection === 'asc' ? 1: -1;
        data.sort((a,b) => {
            let valueA = key(a) ? key(a).toLowerCase() : '';
            let valueB = key(b) ? key(b).toLowerCase() : '';
            return reverse * ((valueA > valueB) - (valueB > valueA));
        });

        //set sorted data to opportunities attribute
        this.opportunities = data;
    }