mat-sort not working on mat-table

baouss picture baouss · Feb 11, 2018 · Viewed 35.8k times · Source

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...

<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>

Answer

VagrantAI picture VagrantAI · Feb 11, 2018

Problem is that next piece of code

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
  }

is happen before you actually got your table in subscription here:

  ngOnInit() {
    this._feedbackService.getFeedback.subscribe(
      res => {
        this.feedbacks = res;
        this.dataSource = new MatTableDataSource(this.feedbacks);
      }
    );

  }

As a possible solution, you could synchronize ngAfterViewInit call and getFeedback subscription via Observable.zip. Please refer to RxJS zip documentation