I am trying to get the mat-table
sorting to work locally, and while I can get the data to show up as expected, clicking on the header row does not do the sortin
matColumnDef name and *matCellDef actual value name should be same
Example:
<ng-container matColumnDef="oppNo">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Opportunity Number</th>
<td mat-cell *matCellDef="let element">{{element.oppNo}}</td>
</ng-container>
In my case oppNo is same for matColumnDef name and *matCellDef name and sorting working fine.
If you read all answers until here and nothing helped, maybe you have the same problem I had.
The problem was that my MatTableDataSource
object
dataSource = new MatTableDataSource<StbElement>(ELEMENT_DATA);
Was used in the html file without this
.
Changing:
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
To:
<table mat-table [dataSource]="this.dataSource" matSort class="mat-elevation-z8">
Fixed the problem.
There were 2 issues for me.
I was getting the data from the service. The ngOnInit sort was not working. Replaced with
ngAfterViewInit() { this.dataSource.sort = this.sort; }
For anyone else who may have this problem: The problem was I didn't read the API reference properly on the angular materials website, the part that said I had to import MatSortModule. After I changed my imports list in app.module.ts to
imports: [
BrowserModule,
MatTableModule,
MatSortModule
],
it worked fine
For anyone that is confused about these namings having to be equal, I did some testing:
This will work (the name of the property is the same as the column def):
<ng-container matColumnDef="version">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
<td mat-cell *matCellDef="let element"> {{element.version}} </td>
</ng-container>
displayedColumns: string[] = ['version']
This will NOT work (the name of the property is not the same as the column def):
<ng-container matColumnDef="version2">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
<td mat-cell *matCellDef="let element"> {{element.version}} </td>
</ng-container>
displayedColumns: string[] = ['version2']
Fyi, this also does NOT work (the length of a property):
<ng-container matColumnDef="length">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
<td mat-cell *matCellDef="let element"> {{element.ids.length}} </td>
</ng-container>
displayedColumns: string[] = ['length']
And neither does this:
<ng-container matColumnDef="ids.length">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
<td mat-cell *matCellDef="let element"> {{element.ids.length}} </td>
</ng-container>
displayedColumns: string[] = ['ids.length']
I had a problem that the sorting function was working but it wasn't sorting properly. I realized that matColumnDef
has to have the same name of the property of my class / interface
that I am referencing in matCellDef
.
According to the Angular Material documentation:
By default, the MatTableDataSource sorts with the assumption that the sorted column's name matches the data property name that the column displays.
For exemple:
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header> NAME </mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.name}} </mat-cell>
</ng-container>
The name
in the matColumnDef
directive has to be the same as the name
used in the <mat-cell>
component.