1

I'm trying to achieve a row action which copies the values of the columns of the previous row, into the row I trigger the action. Seems simple enough, but for some reason, when updating the properties, the datatable does not rerender, or at least doesn't show the changes. This is the code:

actions definition:

const ACTIONS = [
    {label: 'Repetir', name: 'repetir'},
    {label: 'Eliminar', name: 'delete'}
]

custom datatable markup (this is only to add custom types, every other logic from datatable is the same):

<c-custom-data-table
     key-field="Id"
     data={data}
     columns={columns}
     oncellchange={handleCellChange}
     onrowaction={handleRowAction}
     suppress-bottom-bar
     hide-checkbox-column>
</c-custom-data-table>

handleRowAction:

handleRowAction(event){
    const action = event.detail.action;
    const row = event.detail.row;
    switch (action.name) {
        case 'repetir':
            this.doRepetir(row);
            break;        
        case 'eliminar':
            this.doEliminar(row);
            break;
    }
}

the function which makes the changes:

doRepetir(row){
    const rows = this.data;
    const idx = rows.findIndex(dp => dp.ERPvs__Producto__c == row.ERPvs__Producto__c);
    const previousRow = rows[idx - 1];
    if(previousRow.cantidad) rows[idx].cantidad = previousRow.cantidad;
    if(previousRow.precioUnitario) rows[idx].precioUnitario = previousRow.precioUnitario;
    if(previousRow.descuento1) rows[idx].descuento1 = previousRow.descuento1;
    if(previousRow.descuento2) rows[idx].descuento2 = previousRow.descuento2;
    if(previousRow.descuento3) rows[idx].descuento3 = previousRow.descuento3;
    if(previousRow.descuento4) rows[idx].descuento4 = previousRow.descuento4;
    if(previousRow.descuento5) rows[idx].descuento5 = previousRow.descuento5;
    if(previousRow.descuento6) rows[idx].descuento6 = previousRow.descuento6;
    if(previousRow.importeDescuento) rows[idx].importeDescuento = previousRow.importeDescuento;
    this.data = rows;
}

So, I thought that by modifying the properties it would be enought, but for some reason the datatable doesn't react to it. For context:

-the data array is decorated with @track.

-the objects are a custom js class, but I never had a problem with that.

-I checked and the properties are modified as expected.

-All the methods are being called correctly.

-The if statements are working as expected.

Before, I was editing the this.data directly, and when it didn't work, I assigned to rows and then assigned again. This didn't make any difference.

So, When calling the action, visually nothing happens, the row in which I wanted to copy the values remains as it was, but when making a console.log of the object after the method is called, the changes in the properties are seen in the log but not in the datatable. I don't know what is missing here, any help would be appreciated.

2
  • Is the data property decorated with @track? Commented Aug 12, 2021 at 14:48
  • yes , it is. I'm adding it to the question, thanks! Commented Aug 12, 2021 at 14:49

2 Answers 2

1

simply assigning a modified JSON array to a property will not trigger a re-render of your table unless your property is decorated with @track

for more on decorators, you can refer to the documentation, more specifically, Reactivity for Fields, Objects, and Arrays. Quick note, the @track decorator is no longer needed for a variety of scenarios.

In the end, a mutation needs to be detected for a re-render to be triggered, one way of doing this is using a spread operator:

this.data = [...this.data]

another is using a map function to reassign an array of objects to your data property, for example:

this.data = this.data.map(row => row)

2
  • sorry, I don't understand. the data property is decorated with @track, as specified in my question. Commented Aug 12, 2021 at 15:32
  • in that case, use the later approach, technically speaking, @track is not necessary
    – glls
    Commented Aug 12, 2021 at 15:37
0

Try this - which essentially creates a clone of the array and re-assigns it.

this.data  = Object.assign([], rows)
4
  • I'm not creating a new row, I'm modifying an existing one. Commented Aug 12, 2021 at 15:10
  • I updated the answer. Please let me know if either solution works. Commented Aug 12, 2021 at 15:19
  • the first solution doesn't work, and the second one makes all the rows disappear. Commented Aug 12, 2021 at 15:35
  • Oh my bad - The first parameter in object.assign must be an empty array [], not an empty object {}.. Updated my answer Commented Aug 12, 2021 at 15:38

You must log in to answer this question.

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