LWC – dynamically update a datatable column to editable

datatablelightning-web-components

Just need some help to dynamically update a datatable column to make it editable.
In my column definitions – I need to make a stock level column editable based on the results of my @wire call. Stock level is the 5th column.

columns= [
…
  {
    label: "Stock Level",
    fieldName: 'stockLevel',
    type: 'text',
    editable: false
  },
..]

In my @wire where I get the data, I process and check if the stock is editable (just need to check the first orderline for isStockLevelEditable as it would be same for each orderline) – sample code:

@wire(getOrderlines, {
    orderId: '$orderId'
  }) processOrderline({ error, data }) {
    if (data) {
      this.orderlines = data;

       //Check if ordersline stock level is editable
      if(this.orderlines.length != 0){
        if(this.orderlines[0].isStockLevelEditable){
          this.columns[5].editable = true;
          console.log('updated columns ' + JSON.stringify(this.columns));

        }
      }
  }

In the console log I successful see that the column is now editable (editable:true) – however in screen it is still not editable.
What am I missing? Any help would be much appreciated

Best Answer

When dealing with objects, there are two ways LWC knows that a render cycle needs to occur. First, when oldValue !== newValue, which is a memory-address type comparison, a render cycle is automatically triggered, and second, you can use the @track decorator in order to tell LWC that it needs to perform a deep comparison of objects, which will then trigger a render cycle. So, the two main ways you can fix this problem are to either copy the current object, or use track. You do not need to use both, either will suffice.

@track

import { LightningElement, track } from 'lwc'

...

@track columns = [... // omitted for brevity

Copy Array

this.columns[5].editable = true
this.columns = [...this.columns]; // shallow copy array, trigger render