4
votes

I'm using Angular 7 and I have a simple component with an Angular Material Table. Through some event, say a mouse click, I want to be able to update both the data and the header of that existing table.

Before:

enter image description here

After (goal):

enter image description here

Currently, I'm getting the data to update fine. However, I can't get the header text of the columns to update unless, that is, I do a fairly hokey window timeout call.

This is hard to describe, so a stackblitz repo should help. The in 'table-dynamic-columns.example.ts' file I've linked there, I have two different strategies that I try on the 'changeColumnHeader' button click handler. It appears that in order to get my new column header title to show up, I need to first clear out the displayed columns of the table, and then set them back properly in a timeout. Maybe it's not working because the property name stays the same (i.e. 'id') and only the title changes.

Does anyone know a better way to get this to update correctly?

1
Commented out the this.columnsToDisplay = []; and setTimeout() on the stackblitz example you provided and it worked fine.GCSDC
My bad, I made a change last night in the stackblitz without forking it. It's back to demonstrating the problem.Andrew
I had made it so that instead of having an id property for both data sets, they had id1 and id2. That allows everything to refresh properly, but in practice both my data sets will have the same id property so that wouldn't work.Andrew

1 Answers

6
votes

Maybe it's not working because the property name stays the same (i.e. 'id') and only the title changes.

Thats the reason for it not updating, as explained on this comment

On the same comment, there is a proposed solution that you may use (add a trackBy function).

For doing this, include trackBy on your template:

<ng-container [matColumnDef]="config.property" *ngFor="let config of configs; trackBy: trackByIndex">
<th mat-header-cell *matHeaderCellDef> {{config.name}} </th>
<td mat-cell *matCellDef="let element"> {{element[config.property]}} </td>

Include function trackByIndex on your component ts file:

trackByIndex(i) { return i; }

Forked the stackblitz you provided and it is working here