My mat-table is working fine, but when adding mat-sort following the official api documentation, it fails at the ngAfterViewInit with the following message
Cannot set property 'sort' of undefined at ViewFeedbackComponent.ngAfterViewInit
There is already a SO post on this issue (see following link) Mat-table Sorting Demo not Working but I still am not able to get it working.
Does somebody spot the issue? The official example works with a "static" MatTableDataSourcedefined in the component itself, I am querying from my back-end, however.
Any help is greatly appreciated!
MatSortModule is already imported in app.module.ts, mat-sort-header directives are applied to the columns and the ngAfterViewInit is already exactly like in the official example...
import { Component, OnInit, ViewEncapsulation, ViewChild, AfterViewInit} from '@angular/core';
import { Feedback} from '../../../../../models/feedback';
import { FeedbackService} from '../../services/feedback.service';
import { MatTableDataSource, MatSort} from '@angular/material';
@Component({
selector: 'app-view-feedback',
templateUrl: './view-feedback.component.html',
styleUrls: ['./view-feedback.component.css'],
encapsulation: ViewEncapsulation.Emulated
})
export class ViewFeedbackComponent implements OnInit, AfterViewInit {
feedbacks: Feedback[] = [];
showSpinner: boolean = true;
displayedColumns: String[] = [
'id',
'user',
'timestamp',
'stars'
];
dataSource: MatTableDataSource < Feedback > ;
@ViewChild(MatSort) sort: MatSort;
constructor(private _feedbackService: FeedbackService) {}
ngOnInit() {
this._feedbackService.getFeedback.subscribe(
res => {
this.feedbacks = res;
this.dataSource = new MatTableDataSource(this.feedbacks);
}
);
}
ngAfterViewInit() {
this.dataSource.sort = this.sort;
}
}
<div class="mat-tbl-container mat-elevation-z8">
<mat-table #tbl [dataSource]="dataSource" matSort>
<!-- column definitions -->
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header>Id</mat-header-cell>
<mat-cell *matCellDef="let r"> {{r._id}} </mat-cell>
</ng-container>
<ng-container matColumnDef="user">
<mat-header-cell *matHeaderCellDef mat-sort-header>User Id</mat-header-cell>
<mat-cell *matCellDef="let r"> {{r.user}} </mat-cell>
</ng-container>
<ng-container matColumnDef="timestamp">
<mat-header-cell *matHeaderCellDef mat-sort-header>Date</mat-header-cell>
<mat-cell *matCellDef="let r"> {{r.timestamp}} </mat-cell>
</ng-container>
<ng-container matColumnDef="stars">
<mat-header-cell *matHeaderCellDef mat-sort-header>Stars</mat-header-cell>
<mat-cell *matCellDef="let r"> {{r.stars}} </mat-cell>
</ng-container>
<!-- tbl display settings -->
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
The simple solution for this is instead of declaring sorting in ngAfterViewInit, declare after you get the result from the "this._feedbackService.getFeedback.subscribe".
The solution is as below.
The above one works perfectly for me.
Thanks,
I am using the former sort method example from an older version of angular-material. The latest angular-material sort example uses
ngAfterViewInit()
to call sortthis.dataSource.sort = this.sort;
I was unable to get sort to work using the new example. The older sort method uses extends DataSource . I was able to import DataSource using a new path `import { DataSource } from '@angular/cdk/table';I redefined the connect mehod inheriting from MatTableDataSource bad idea...
Problem is that next piece of code
is happen before you actually got your table in subscription here:
As a possible solution, you could synchronize
ngAfterViewInit
call andgetFeedback
subscription viaObservable.zip
. Please refer to RxJS zip documentationIn angular 7 use the following example for two Paginators but replace paginator with sort.
https://stackblitz.com/edit/data-table-multiple-data-source
Here is a duplicate of this question:
Multiple mat-table with MatSort within the same component