Reputation: 550
I am using angular along with angular material to create a mat table. Everything works fine. Its just that I see an error in console which I not able to figure out how to rectify it. Again I see my data loaded, pagination works, but I do observe an error on console which I don't want. How can I correct this.
MessageDataTableDataSource.ts
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator, MatSort } from '@angular/material';
import { map } from 'rxjs/operators';
import { Observable, of as observableOf, merge } from 'rxjs';
import { MessageData } from '../../data-model/MessageData';
export class MessageDataTableDataSource extends DataSource<MessageData> {
constructor(private paginator: MatPaginator,
private sort: MatSort, private data: MessageData[]) {
super();
}
connect(): Observable<MessageData[]> {
const dataMutations = [
observableOf(this.data),
this.paginator.page,
this.sort.sortChange
];
this.paginator.length = this.data.length;
return merge(...dataMutations).pipe(map(() => {
return this.getPagedData(this.getSortedData([...this.data]));
}));
}
disconnect() {}
private getPagedData(data: MessageData[]) {
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
return data.splice(startIndex, this.paginator.pageSize);
}
private getSortedData(data: MessageData[]) {
if (!this.sort.active || this.sort.direction === '') {
return data;
}
return data.sort((a, b) => {
const isAsc = this.sort.direction === 'asc';
switch (this.sort.active) {
case 'id': return compare(+a.Message.Id, +b.Message.Id, isAsc);
default: return 0;
}
});
}
}
function compare(a, b, isAsc) {
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
HTML Template
<div class="mat-elevation-z8">
<table mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
<!-- Id Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Id</th>
<td mat-cell *matCellDef="let row">{{row.message.id}}</td>
</ng-container>
<!-- Message Text Column -->
<ng-container matColumnDef="messageText">
<th mat-header-cell *matHeaderCellDef mat-header>Message Text</th>
<td mat-cell *matCellDef="let row">{{row.message.messageText}}</td>
</ng-container>
<!-- Delivery Date -->
<ng-container matColumnDef="deliveryDate">
<th mat-header-cell *matHeaderCellDef mat-header>Delivery Date</th>
<td mat-cell *matCellDef="let row">{{row.message.deliveryDateTime}}</td>
</ng-container>
<!-- Status Column -->
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-header>Status</th>
<td mat-cell *matCellDef="let row">{{row.message.messageStatus}}</td>
</ng-container>
<!-- Action Column -->
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef mat-header>Action</th>
<td mat-cell *matCellDef="let row">
<button type="button" class="btn btn-danger"
[disabled]="row.message.messageStatus != 'PENDING'"
(click)="cancelScheduledMessage()">Cancel</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator #paginator
[length]="dataSource.data.length"
[pageIndex]="0"
[pageSize]="5"
[pageSizeOptions]="[5, 10, 50, 100]">
</mat-paginator>
</div>
MessageListComponent.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatSort, MatPaginator } from '@angular/material';
import { MessageDataTableDataSource } from './message-data-table-datasource';
import { MessageService } from '../message.service';
import { MessageData } from '../../data-model/MessageData';
@Component({
selector: 'app-message-list',
templateUrl: './message-list.component.html',
styleUrls: ['./message-list.component.css']
})
export class MessageListComponent implements OnInit {
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
dataSource: MessageDataTableDataSource;
displayedColumns = ['id', 'messageText', 'deliveryDate', 'status', 'action'];
constructor(private messageService: MessageService) { }
ngOnInit() {
this.messageService.getMessages().subscribe(
(messageData: MessageData[]) => {
this.dataSource = new MessageDataTableDataSource(this.paginator,
this.sort, messageData);
},
(error) => console.log(error)
);
}
}
Looking forward to kind suggestions. Thanks
Upvotes: 0
Views: 575
Reputation: 222552
You can handle this error by using *ngIf
OR safe navigation operator (?) .
Reason: It's just a console error that occurs when you try to access the datasource in the template before the actual value is set on the component. this happens because the data is assigned asynchronously.
Solution:
<mat-paginator #paginator
[length]="dataSource?.data?.length"
[pageIndex]="0"
[pageSize]="5"
[pageSizeOptions]="[5, 10, 50, 100]">
</mat-paginator>
Upvotes: 1