This table is not very user friendly, and it forces you to manually update, which misses the point of using Angular for the bindings. It is stated in the documentation that:
Since the table optimizes for performance, it will not automatically check for changes to the data array. Instead, when objects are added, removed, or moved on the data array, you can trigger an update to the table's rendered rows by calling its renderRows() method.
To call a method on the material table component from the Typescrypt code you need to do it through a ViewChild
reference to the table. First add a hashtagged name to the table in the template:
<table #myTable mat-table ... >
Then on your Typescript file, declare a public member with the same name you put after the hashtag in the template, and decorate it with ViewChild
so that Angular injects it (I wont be showing the imports):
export class SomeComponent implements OnInit {
@ViewChild(MatTable) myTable!: MatTable<any>;
(The "!" is needed in new versions of Angular to trick Typescript into believing it will be always non null. Turns out it will. Keep reading)
So now you could do:
this.myTable.renderRows();
And it would work unless the table or any of the parent is inside an *ngIf
directive. When that directive is working, the table is not present in the DOM, and the member annotated with ViewChild
will be undefined, so you can't call anything on it. This is not a problem of the material table in particular, it is how Angular is designed. Check this question for solutions. My favourite is to replace the *ngIf
with [hidden]
. That is ok if the directive was in the table, but becomes messy when it is in the parents.