Issue
I want to connect rest api data source to material table. This works for simple table but material table doesn’t show any data.
This is the markup for simple table that works fine:
<!-- simple table -->
<table border="1">
<thead>
<tr>
<th>id</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let x of list_product">
<td>{{x.id}}</td>
<td>{{x.description}}</td>
</tr>
</tbody>
</table>
<!-- end of simple table -->
But this markup for a material table doesn’t show the data:
<!-- material table -->
<table mat-table>
<!-- Position Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let x of list_product"> {{x.id}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let x of list_product"> {{x.description}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<!-- end of material table -->
This is my Typescript code that call table from node:
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { analyzeAndValidateNgModules } from '@angular/compiler';
@Component({
selector: 'app-basic',
templateUrl: './basic.component.html',
styleUrls: ['./basic.component.scss']
})
export class BasicComponent implements OnInit {
public list_product:any=[];
displayedColumns: string[] = ['id', 'description'];
constructor(private http:HttpClient) { }
ngOnInit(): void {
this.get_data();
}
get_data()
{
this.http.get("http://localhost:3000/listp").subscribe(
(res)=>{
for(var i=0;i<res['length'];i++){
this.list_product.push(res[i]);
}
}//end res
)
}
}
Solution
Your simple table and material table works differently. Therefore –
- in your template, you need to bind
list_product
to thedataSource
property ofmat-table
- in your component code, you need to replace the
list_product
each time you receive a new response – populatinglist_product
with items one by one will not update the table’sdataSource
.
Modify your table as –
<table mat-table [dataSource]="list_product">
<!-- Position Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let product"> {{product.id}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let product"> {{product.description}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
and change the get_data()
method to –
get_data(){
this.http.get<any>("http://localhost:3000/listp").subscribe(
res => this.list_product = res
);
}
For further details, check the documentation