Reputation: 15
I have a child component that uses MatTable. I need to update the table after edit or create using renderRows(); The table datasource is an @Input(). I have tried onChanges, but I got undefined because of @ViewChild.
Where do I have to put renderRows() to update the table when products[] is updated? In this case, the table is updated, but with an undefined error message.
Child Component:
//Table datasource
@Input()
products: Product[] = [];
@ViewChild(MatTable)
table !: MatTable<Product>;
ngOnChanges(){
this.table.renderRows(); //works but I got undefined
}
In the parent component, when the state changes:
this.productService.saveProduct(product).subscribe({
next: data => {
this.products.push(data);
}
});
If I instead reload and create a new array, it works perfect, but I don't want to call my rest api:
loadProducts() {
this.productService.getProducts().subscribe({
next: data => { this.products = data }
});
}
this.productService.saveProduct(product).subscribe({
next: data => {
this.loadProducts()
}
});
Upvotes: 0
Views: 1488
Reputation: 15
Potencial solution 1:
Now I dont have undefined and the the works perfect, but repeat twice the same line looks wrong for me.
ngAfterViewInit() {
this.dataSource = new MatTableDataSource(this.products);;
this.table.renderRows();
}
ngOnChanges(){
this.dataSource = new MatTableDataSource(this.products);
}
Potencial solution 2:
Parent component always creates a new array when something changes:
this.productService.saveProduct(product).subscribe({
next: data => {
this.products.push(data);
this.products = Array.from(this.products);
}
});
Upvotes: 0
Reputation: 10954
Simply check that the table is defined before calling the function
@ViewChild(MatTable)
table?: MatTable<Product>;
ngOnChanges(){
if (table) this.table.renderRows(); //works but I got undefined
}
!
means that the variable is always defined, which in this case is not true. Use ?
in these situations and the compiler will help you avoid these types of bugs.
I see that you are hoping ngOnChanges
will fire when you change the array Products
. This is not the case as change detection will only check object identity, not value. You can call ngOnChanges
directly, reassign the array after pushing, or simply create an update function - up to you.
this.productService.saveProduct(product).subscribe({
next: data => {
this.products.push(data);
this.ngOnChanges();
}
});
or
this.productService.saveProduct(product).subscribe({
next: data => {
this.products.push(data);
this.products = this.products.slice();
}
});
or
renderRows(){
this.table?.renderRows();
}
this.productService.saveProduct(product).subscribe({
next: data => {
this.products.push(data);
this.renderRows();
}
});
Upvotes: 1