0

I have a lightning datatable where I am displaying data that is coming from an API. I have a combobox that gets the data from the same API - I loop through the same response and get the 'unique' values so I could use them as filter.

Now, I have used this native JS filter function to filter the datatable's data:

controller.js

handleComboChange(event){
   this.firstVal = event.detail.value;
   this.handleFilterData(this.ltgTableData);
   this.handleLtgDataTable();
}

handleFilterData = (tableDataList) => {
    this.ltgTableData = tableDataList.filter(
        record => (this.firstVal === 'All' || record.memberName+'- ' +record.relationship === this.firstVal)
    )
}

handleLtgDataTable(){
    let tableLen = this.ltgTableData.length;
    if(tableLen>1){
        this.showTable = true;
    } 
}

Html

<lightning-combobox label="Engine" name="Engine" value={firstVal} 
                    options={dataForCombo} onchange={handleComboChange}>
</lightning-combobox>

<template if:true={showTable}>
        <c-nxp-lightning-datatabe tabledata={ltgTableData} columns={dataColumns} ></c-nxp-lightning-datatabe>
</template>

When ever I change the combobox, I see a change in the this.ltgTableData on the console, and this.showTable also getting updated. But, the lightning-datatable is not refreshing. When I observed is, whenever I click on the column header for sorting, the data is refreshing based on the filter value I have selected.

Update: Even after converting ltgTableData into a map, and iterate over the values, it doesn't render the lightning datatable after the filter. Any other recommendations?

7
  • Could you add the declaration of ltgTableData ? But I already recommend to you to create a getter for it, probably it is being detected the mutation of the variable, but we need more information Commented Dec 14, 2022 at 0:34
  • 1
    One question from me, are you using the @track decorator for your ltgDataTable attribute? Commented Dec 16, 2022 at 21:51
  • Also is the nested datatable your own custom component, or is it an installed product? Commented Dec 16, 2022 at 21:57
  • Hi @CallumMacErlich, Yes, I have used @ track decorator and found no difference. Also, I am using my custom component for the data table, which adds some pagination and sorting, which are common across our org.
    – SatyaV
    Commented Dec 18, 2022 at 6:36
  • 1
    Please include c-nxp-lightning-datatabe's part where tabledata is used. I have a strong suspicion that the value is copied to another field in a place like connectedCallback, which is fired just once and then there is no further tracking of the field. Commented Dec 20, 2022 at 11:14

3 Answers 3

3

filter() does not mutate the array on which it is called, thus the changes are not detected, and your component is not rerendered.

You would need to use a map() function for the mutation to occur.

ex:

 this.ltgTableData = tableDataList.filter(
    record => (this.firstVal === 'All' || record.memberName+'- ' +record.relationship === this.firstVal)
).map( res => res);

(I think the above should work)

4
  • How can I filter the records if I use a map? I mean, when I chose a value from the combobox options, how can I extract the matched records and push to the table?
    – SatyaV
    Commented Dec 14, 2022 at 14:29
  • you can filter, and then use map, to iterate and return a new array to your variable
    – glls
    Commented Dec 14, 2022 at 14:31
  • 1
    or just use map, and in your return statement, copy each prop, add a condition which matches the one in your filter to only modify that attribute. all add an example shortly
    – glls
    Commented Dec 14, 2022 at 14:32
  • I've tried this approach now, still the problem persists. The table is not getting refreshed. I'm making further "trail & errors" to see if I am doing something wrong.
    – SatyaV
    Commented Dec 14, 2022 at 16:21
1
+50

The problem you're facing is the mutation of the object (in javascript, an Array is a special type of Object)

Track Changes Inside Objects and Arrays: However, the framework doesn't observe mutations made to complex objects, such as objects inheriting from Object, class instances, Date, Set, or Map. https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.reactivity_fields

so change your code to this:

    handleFilterData = (tableDataList) => {
    this.ltgTableData = [... tableDataList.filter(
        record => (this.firstVal === 'All' || record.memberName+'- ' +record.relationship === this.firstVal)]
       )
    }

if it doesn't work, I suggest to create a getter:

    get ltgTableData() {
        return [... tableDataList.filter(
        record => (this.firstVal === 'All' || record.memberName+'- ' +record.relationship === this.firstVal)]
    }
0

You can probably try to display spinner or datatable. Now when the component needs to be refreshed, display only the loading spinner till the data is filtered in JS. After that display the datatable. I will illustrate as below:

handleComboChange(event){

   this.showTable = false; // CHANGE WHICH I AM HIGHLIGHTING


   this.firstVal = event.detail.value;
   this.handleFilterData(this.ltgTableData);
   this.handleLtgDataTable();
}
2
  • 1
    Hello, I believe I've tried this approach earlier. I can give it a try first thing on Monday. I will keep you posted.
    – SatyaV
    Commented Dec 18, 2022 at 6:37
  • 2
    I solved the same problem with a getter, I can post the code on Monday if this approach doesn't work, @ArnoldJr. Commented Dec 19, 2022 at 0:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .