[SalesForce] How to make columns lwc lightning-datatable dynamic with button-icon

I have a lwc component with a lightning-datatable with the first column as a button-icon. This works when the columns are defined as a constant.

Constant working

const columns = [
    {
        label: 'View',
        type: 'button-icon',
        initialWidth: 75,
        typeAttributes: {
            iconName: 'action:preview',
            title: 'Preview',
            variant: 'border-filled',
            alternativeText: 'View'
        }
      },
 {fieldName: 'Name', label: 'NAME', type: 'text'},
{fieldName: 'BillingCity', label: 'CITY', type: 'text'},
{fieldName: 'BillingCountry', label: 'COUNTRY', type: 'text'},
{fieldName: 'BillingPostalCode', label: 'POSTAL CODE', type: 'text'},
{fieldName: 'Phone', label: 'PHONE', type: 'text'},
{fieldName: 'Owner.name', label: 'OWNER', type: 'text'}
];

Is it possible to make all the other columns dynamic except for the button-icon? I tried the following but this is not working. Adding columns & fields from metadata to icon column:

const columns = [
    {
        label: 'View',
        type: 'button-icon',
        initialWidth: 75,
        typeAttributes: {
            iconName: 'action:preview',
            title: 'Preview',
            variant: 'border-filled',
            alternativeText: 'View'
        }
      }
];





 @wire(getDynamicTableDataList, { TableName: '$objectListApiName' })
    wiredContacts({ error, data }) 
    {
        if(data) 
        {
           let sObjectRelatedFieldListValues = [];
            
           for (let row of data.lstDataTableData) 
           {
                const finalSobjectRow = {}
                let rowIndexes = Object.keys(row); 
                rowIndexes.forEach((rowIndex) => 
                {
                    const relatedFieldValue = row[rowIndex];
                    if(relatedFieldValue.constructor === Object)
                    {
                        this._flattenTransformation(relatedFieldValue, finalSobjectRow, rowIndex)        
                    }
                    else
                    {
                        finalSobjectRow[rowIndex] = relatedFieldValue;
                    }
                    
                });
                sObjectRelatedFieldListValues.push(finalSobjectRow);
            }
            this.DataTableResponseWrappper = data;
             console.log(data.lstDataTableColumns);
        const col = columns.concat(data.lstDataTableColumns);
        console.log(col);
            this.finalSObjectDataList = sObjectRelatedFieldListValues;
        } 
        else if (error) 
        {
            this.error = error;
        }
    }

I debugged the following:

const col = columns.concat(data.lstDataTableColumns);
            console.log(col);

this seems correct but is not rendering as suspected see:
enter image description here

How do I achieve this? Thanks in advance

Best Answer

Define the class level attribute to store the columns, columns. From the wired method add the dynamic columns to that.

export default class MyComponent extends LightningElement {

    @track columns = [
        {
            label: 'View',
            type: 'button-icon',
            initialWidth: 75,
            typeAttributes: {
                iconName: 'action:preview',
                title: 'Preview',
                variant: 'border-filled',
                alternativeText: 'View'
            }
          }
    ];
    
    
    @wire(getDynamicTableDataList, { TableName:'$objectListApiName' })
    wiredContacts({ error, data }) 
    {
        if(data) {
            this.columns = [...this.columns, ...data.lstDataTableColumns];
        }
    }
}
Related Topic