Bohao LI
Bohao LI

Reputation: 2723

matSort not working properly in mat-table Angular

My .html file:

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

  <ng-container matColumnDef="uid">
    <!--<mat-header-cell *matHeaderCellDef mat-sort-header>Building UID</mat-header-cell>-->
    <mat-header-cell *matHeaderCellDef mat-sort-header>
      Building UID
    </mat-header-cell>
    <mat-cell *matCellDef="let tree" padding>{{tree.uid}}</mat-cell>
  </ng-container>

  <ng-container matColumnDef="address">
    <mat-header-cell *matHeaderCellDef mat-sort-header>
      Address
    </mat-header-cell>
    <mat-cell *matCellDef="let tree" padding>{{tree.location.address}}</mat-cell>
  </ng-container>

  <ng-container matColumnDef="zipCode">
    <mat-header-cell *matHeaderCellDef mat-sort-header>
      Zip code
    </mat-header-cell>
    <mat-cell *matCellDef="let tree" padding>{{tree.location.zipCode}}</mat-cell>
  </ng-container>

  ...

  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>

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

</mat-table>

My .ts file:

@Component({
  selector: 'page-buildings',
  templateUrl: 'buildings.html',
})
export class BuildingsPage {
  @ViewChild(MatSort) sort: MatSort;
  ...
  private displayedColumns: string[] = ["uid", "address", "zipCode", "city", "country", "treeDetails"]; // tslint:disable-line
  private dataSource: MatTableDataSource<any>;

  ...
  constructor(...) {

    this.dataSource = new MatTableDataSource(...);
    this.dataSource.sort = this.sort;
  }
  ...
}


But in my mat-table, the sort only works for the first column "uid", not for the others.

I've learnt from this link(first answer) that in *matColumnDef="firstString" and {{tree.secondString}}, firstString must equal to secondString to make it work, but in my case, it's tree.firstString.secondString, I've used two points.

Any idea why this is happening and how to make it work?



Please look at the picture: enter image description here

When I click on column "Building UID", the mat-table will be sorted, everything works well. But when I click on other columns, (address, zip code, city, country), it will only sort the first two rows, and only the ascending sort works (the descending sort does not work), and the rest of the rows are not sorted at all.

Upvotes: 2

Views: 3441

Answers (2)

Bohao LI
Bohao LI

Reputation: 2723

In my case, I've done the following to make it work.

this.dataSource.sortingDataAccessor = ((data: any, sortHeaderId: string) => {
  let toReturn: any;
  if (sortHeaderId === 'uid')
    toReturn = data[sortHeaderId];
  else
    toReturn = data.location[sortHeaderId];
  if (typeof toReturn === 'string')
    toReturn = toReturn.toLowerCase();
  return toReturn;
});

Upvotes: 0

J. S.
J. S.

Reputation: 2376

You need to overwrite the sortingAccessor:

  this.datasource.sortingDataAccessor = ((item: TableItems, sortHeaderId: string) => {
      return item.data[sortHeaderId];
    });

In this case the data is hold one level deeper in item.data instead of item.

Upvotes: 2

Related Questions