I'm currently learning to use Angular with Material UI and want to display a table. I'm loading my data through an combination of In-Memory DB and HTTP Interception. My problem is that my table does not update when it receives new data.
For the table I use the generated component provided by Angular Material. When I update my table data I can see during debugging that the Array the table holds is updated with the desired data. However, only if I change sorting or pagination the data is actually refreshed in my table.
For some reason the observable in connect()
(see below) is not called when my data changes.
What am I missing that is needed to trigger the table refreshment?
TableComponent:
export class TableComponent implements AfterViewInit {
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatSort) sort!: MatSort;
@ViewChild(MatTable) table!: MatTable<TableItem>;
dataSource: TableDataSource;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['id', 'name'];
constructor(private tableService: TableService) {
this.dataSource = new TableDataSource(tableService);
}
isActive = false; // does not interact with table!
ngAfterViewInit(): void {
this.getTableData();
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
this.table.dataSource = this.dataSource;
}
public getTableData():void{
this.dataSource.getTableData();
}
TableDataSource:
export class TableDataSource extends DataSource<TableItem> {
data: TableItem[] = [];
paginator: MatPaginator | undefined;
sort: MatSort | undefined;
constructor(private tableService: TableService) {
super();
}
/**
* Connect this data source to the table. The table will only update when
* the returned stream emits new items.
* @returns A stream of the items to be rendered.
*/
connect(): Observable<TableItem[]> {
if (this.paginator && this.sort) {
// Combine everything that affects the rendered data into one update
// stream for the data-table to consume.
return merge(observableOf(this.data), this.paginator.page, this.sort.sortChange)
.pipe(map(() => {
return this.getPagedData(this.getSortedData([...this.data ]));
}));
} else {
throw Error('Please set the paginator and sort on the data source before connecting.');
}
}
[....]
public getTableData():void{
this.tableService.getTableItems()
.subscribe(items => {
this.data = items;
});
}