11

In my Angular app (using Angular Material) I have several tables.

The strange thing is that, in one case, sorting works, while, in another case, it doesn't.

Here is the table that works:

<table mat-table [dataSource]="dataSource" matSort>

  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef> ID </th>
    <td mat-cell *matCellDef="let row"> {{row.id}} </td>
  </ng-container>

  <ng-container matColumnDef="firstName">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th>
    <td mat-cell *matCellDef="let row"> {{row.firstName}} </td>
  </ng-container>

  <ng-container matColumnDef="lastName">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </th>
    <td mat-cell *matCellDef="let row"> {{row.lastName}} </td>
  </ng-container>

  <ng-container matColumnDef="viewProfile">
    <th mat-header-cell *matHeaderCellDef class="viewProfile"> Profile </th>
    <td mat-cell *matCellDef="let row" class="viewProfile">
      <button mat-icon-button (click)="openProfile(row.id)">
                <mat-icon aria-label="icon-button with a page-view icon">pageview</mat-icon>
              </button>
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

</table>

... and here is the table that doesn't work:

<table class="table2" mat-table [dataSource]="dataSource2" matSort>

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Project </th>
    <td mat-cell *matCellDef="let row"> {{row.name}} </td>
  </ng-container>
  <ng-container matColumnDef="role">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Role </th>
    <td mat-cell *matCellDef="let row"> {{row.role}} </td>
  </ng-container>
  <ng-container matColumnDef="beginning">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Beginning </th>
    <td mat-cell *matCellDef="let row"> {{row.beginning | date : "mediumDate"}} </td>
  </ng-container>
  <ng-container matColumnDef="end">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> End </th>
    <td mat-cell *matCellDef="let row"> {{row.end | date : "mediumDate"}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns2"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns2;"></tr>
</table>

As you can see, in both cases I use "matSort" (in the table tag) and "mat-sort-header" (for the columns that are supposed to be sortable).

Furthermore, in each case I do the same import in the component.ts file:

import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material';

I just don't get why sorting works in the first case but not in the second. Does anybody have any ideas what's going on here?

4
  • Which version of Angular Material are you using? Commented Aug 21, 2018 at 20:59
  • does your dataSource support sorting? Can you post plunkr? Commented Aug 21, 2018 at 21:11
  • I'm using Angular Material 6 Commented Aug 22, 2018 at 15:14
  • the datasource in the second case contains apart from strings two dates ... may that be a reason? Commented Aug 22, 2018 at 15:15

5 Answers 5

32

Make sure that the column_name in the displayedColumns array,

displayedColumns = ['column_name'];

the html container,

ng-container matColumnDef="column_name"

and the keys of the dataSource objects,

dataSource = [ {"column_name": "value"} ];

ALL MATCH PERFECTLY.

This can also be the reason that a specific set of data doesn't work and others do.

Sign up to request clarification or add additional context in comments.

1 Comment

I had the same issue. This solution works. Make sure column names and columnDef are the same.
18

Are you sure your second table ( the one where sort is not working ) is not wrapped in a div with *ngIf ? Because that is a common problem, as when the template is rendered, because of the *ngIf, matSort is undefined. Here is how to fix it : Angular 5 Material Data Table sorting not working

2 Comments

Thank you for your suggested answer ... the table is wrapped inside several divs but none of these divs is with *ngIf
thank you for your suggested answer <3 I used ngIf in mat-table tags. I removed it after sorting works :)
3

For data loaded using an API call:

It's possible that the sort was set before the data was loaded onto the table; thereby messing up sorting feature.


In that case, change:

** code to insert data into the table **

this.dataSource2.sort = this.sort;

To

** code to insert data into the table **

setTimeout(() => this.dataSource2.sort = this.sort, 2000); // Delay it by 2 seconds.

Where this.sort is:

@ViewChild(MatSort, { static: false }) sort: MatSort;

1 Comment

Thanks, this was the solution for me, making sure to set this.dataSource2.sort = this.sort; after the data loads. However, as long as you're using async/await correctly when calling external APIs there's no need for using setTimeout, which is a really bad code smell.
0

There is also another possible issue. Besides that column names have to match the attribute 'matHeaderRowDef' in 'mat-header-row *matHeaderRowDef', the column name also has to match the class field/property name of the content type used in the dataSource attribute.

e.g.

<mat-table [dataSource]="mySource" matSort>
        <!-- modelViewFieldNameOne has to match the class field/property name! -->
        <ng-container matColumnDef="modelViewFieldNameOne">
            <mat-header-cell  *matHeaderCellDef
                             mat-sort-header>just a column</mat-header-cell>
            <mat-cell *matCellDef="let tableItem">{{ tableItem.getterForMyField }}</mat-cell>
        </ng-container>


// typescript where 'mySource' is kept
mySource = new MatTableDataSource<MyModelViewType>();


// typescript of MyModelViewType
export class MyModelViewType{

   // this is important, it has to match the ng-container matColumnDef attribute!!!
   private modelViewFieldNameOne

   // this getter naming is not important for mat-table attributes
   public get getterForMyField(): string { 
     return this.modelViewFieldNameOne;
   }
}

My mat-table was sorting fine, until the model view type (i.e. MyModelViewType in the example above) was re-factored but only the field / property name changed, the getter() name was kept, the corresponding table column stopped sorting properly. Once the attribute matched the name it worked again.

I am using: @angluar/cdk 9.2.2

Comments

-1

I know my sort doesn't work when it thinks I mixed in data types. So on the list below it will stop sorting the Value column when it gets to the 587.
enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.