Angular Material Table - Issues with async dataSource
15,741
You're assigning the new MatTableDataSource(this.invoices);
to the this.dataSource.data
but the data object is just the raw data. So just fix your code to
this.dataSource = new MatTableDataSource(this.invoices);
and you should be good.
Tipp: The MatTable datasource does not has to be a MatTableDataSource element. You can just pass the raw data to the [dataSource] attribute.
Author by
Admin
Updated on June 09, 2022Comments
-
Admin almost 2 years
I'm trying to populate an Angular Material table with data loaded asynchronously from AWS DynamoDB, but the best I can do is render the table with the three expected items all returning properties in each cell as '[object Object]'.
The process works like this:
- At AllInvoicesComponent.ngOnInit(), do buildTable(),
- Await DataService.getItems('invoices'),
- Assign dataSource as new MatTableDataSource(AllInvoicesComponent.invoices)
The 'async' pipe also does absolutely nothing for the
dataSource
attribute of thetable
.data.service.ts:
import { Injectable } from '@angular/core'; import * as aws from 'aws-sdk'; import { Observable } from 'rxjs'; import AuthService from '@app/services/auth.service'; @Injectable({ providedIn: 'root' }) export class DataService { dynamodb; docClient; constructor(private auth: AuthService) { aws.config.credentials = new aws.Credentials(auth.credentials.accessKeyId, auth.credentials.secretAccessKey, null); aws.config.update({ region: 'eu-west-1' }) this.dynamodb = new aws.DynamoDB(); this.docClient = new aws.DynamoDB.DocumentClient(); } async getItems(tableName) { const params = { TableName: tableName } return new Promise((resolve, reject) => { this.dynamodb.scan(params, (err, data) => { if (err) { reject(err); } else { resolve(data.Items); } }) }) } }
all-invoices.component.ts:
import { Component, OnInit, ViewChild } from '@angular/core'; import { Observable, from } from 'rxjs'; import {MatPaginator, MatSort, MatTableDataSource} from '@angular/material'; import Invoice from '../invoice.interface'; import { DataService } from '../../services/data/data.service'; @Component({ selector: 'app-all-invoices', templateUrl: './all-invoices.component.html', styleUrls: ['./all-invoices.component.scss'] }) export class AllInvoicesComponent implements OnInit { invoices; dataSource: MatTableDataSource<any>; @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; tableColumns = [ 'number', 'reference' ] constructor(private database: DataService) { } ngOnInit() { this.buildTable(); } async buildTable() { try { this.invoices = await this.database.getItems('invoices'); this.dataSource = new MatTableDataSource(this.invoices); } catch(err) { console.error(`Error retrieving invoices: ${err.Message}`); // TODO: } } }
all-invoices.component.html:
<p>All Invoices</p> <br> <div class="spinner-container" *ngIf="dataSource.loading$ | async"> <mat-spinner></mat-spinner> </div> <table mat-table [dataSource]="dataSource" matSort> <ng-container matColumnDef="number"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Number</th> <td mat-cell *matCellDef="let invoice">{{invoice.number}}</td> </ng-container> <ng-container matColumnDef="reference"> <th mat-header-cell *matHeaderCellDef mat-sort-header>Reference</th> <td mat-cell *matCellDef="let invoice">{{invoice.reference}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="tableColumns"></tr> <tr mat-row *matRowDef="let row; columns: tableColumns"> </table> <mat-paginator [length]="dataSource.length" [pageSize]="25" [pageSizeOptions]="[5, 10, 25, 50]"></mat-paginator>