How to convey LWC’s complex Reactive property back to markup?

From SF docs:

There are some limitations on the depth of changes tracked for
rerendering in reactive properties. The tracking depth depends on the
type of the reactive property.

Lightning Web Components tracks changes to the internal values of
these types of reactive properties:

  1. Primitive values
  2. Plain objects created with {…}
  3. Arrays created with []

Also SF does not track for complex types like Date.

Now what I wanna do is track an Array of complex object. If a new element is added subtracted from the array re-render the UI. Classic Data – table example.

So I declared my Markup:

<template>
    <h1>Hello </h1>
    <lightning-datatable
                key-field="id"
                data={data}
                columns={columns}
                is-loading={tableLoadingState}>
            </lightning-datatable>

            <lightning-button variant="brand" label="Add row" title="Add row" onclick={addRow} class="slds-m-left_x-small"></lightning-button>
</template>

JS:

import { LightningElement, track } from 'lwc';
const columns = [
    { label: 'Label', fieldName: 'name', type:"text"},
    { label: 'Website', fieldName: 'website', type: 'text' },
    { label: 'Phone', fieldName: 'phone', type: 'text'  }
];
export default class App extends LightningElement {
    @track data = [{name:'Mylabel' , website:'google.com' ,phone :'74126478963',amount : 45  }];
    @track columns = columns;
    @track tableLoadingState = false;

    addRow(){
        console.log('add row called');
        this.data.push({name:'Mylabel2s' , website:'2google.com' ,phone :'74126478963',amount : 45 });
        console.log(JSON.stringify(this.data));
        //this.data =[];

    }


}

When I save and try running this I get the message as shown in docs.

[LWC warning]: Property "_def" of [object:vm undefined (0)] is set to a non-trackable object, which means changes into that object cannot be observed.
<lightning-primitive-header-factory>

which means I cannot track the row data for lightning-datatable, which also means when I add or remove rows I would be unsuccessful.

I could not find a solution to add row in datatable and get it updated back in the markup, I searched dev guide and recipe book. Is this a limitation? or there is a workaround?

Playground Link

Answer

Well, I was able to fix this by using the ES6 Spread operator, which basically splits the array into the individual element and then recreate array…

addRow(){


        this.data = [...this.data ,{name:'Mylabel2s' , website:'2google.com' ,phone :'74126478963',amount : 45 } ];

    }

Playground link

Attribution
Source : Link , Question Author : Pranay Jaiswal , Answer Author : Pranay Jaiswal

Leave a Comment