1

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

2 Answers 2

2

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
2
  • Thanks sfdcfox - the second option (copy array) worked. I already had @track on the column so that wasn't working. Will read around to understand how this works
    – Amul Shah
    Commented Nov 19, 2021 at 22:19
  • Amul Can you share the whole code please? i need to make my columns editable as welll
    – user110654
    Commented Sep 29, 2022 at 12:33
0

The way I got this to work (as neither @track nor this.columns = [...this.columns]; worked for me):

I had a wired call to get the user information, and allow editing if the user's profile is System Admin. When putting the this.isUserAdmin value into the columns definition, it would not re-evaulate when the wire came back. So I set the columns using a function, and when the wire results are returned, I re-initialize the columns.

Example (note: only an excerpt of important parts of my code):

user;
@wire(getRecord, { recordId: USER_ID, fields: USER_FIELDS }) wireuser({ error, data }) {
    if (data) {
        this.user = data;
        this.columns = this.getColumns();
    }
}

get userProfileName() { return getFieldValue(this.user, USER_FIELD_ProfileName); }
get isUserAdmin() {
    if (this.userProfileName == 'System Administrator') return true;
    return false;
}//isUserAdmin

columns = this.getColumns();

getColumns() {
    return [
        ...
        {
            label: 'Field Label'
            , fieldName: 'Field__c'
            , type: 'text'
            , editable: this.isUserAdmin
            , sortable: true
            , hideDefaultActions: true
            , wrapText: true
        },
        ...
    ];
}//getColumns

You must log in to answer this question.

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