Mat-table reset mat-sort to initial state

Issue

I have a mat-table in which I have several sort-able column. I can set the initial sort of the table with the matSortActive and matSortDirection properties on the mat-table. Using this, the arrow indicating the sorting direction in the headers is displayed correctly.

Now when I am trying to reset the sorting to the initial state by using a button the sorting is correctly reset. However, the arrow in the header is not updated. So the arrow is still displayed in the header of the previous sorted column.
How can I get the arrow to be displayed in the initial state again?

My table and reset button in HTML:

<button mat-button mat-raised-button (click)="removeFilters()" class="reset-button">Verwijder filters</button>

<mat-table #table [dataSource]="dataSource" matSort (matSortChange)="sortData($event)" matSortActive="comp_name_sort" matSortDirection="asc">
  <ng-container matColumnDef="assetName">
    <mat-header-cell *matHeaderCellDef mat-sort-header="comp_name_sort">Systeem</mat-header-cell>
    <mat-cell *matCellDef="let asset"> {{asset.comp_name}} </mat-cell>
  </ng-container>

  <ng-container matColumnDef="softwareName">
    <mat-header-cell *matHeaderCellDef mat-sort-header="soft_name_sort">Software</mat-header-cell>
    <mat-cell *matCellDef="let asset"> {{asset.soft_name}} </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:

  export class AssetsComponent implements OnInit {

  @ViewChild(MatSort) sort: MatSort;

  assets: Asset[];
  displayedColumns = ['assetName', 'softwareName',];
  dataSource = new MatTableDataSource<Asset>(this.assets);

  constructor( private assetsService: AssetsService) { }

  ngOnInit() {
    this.getAssets();
  }

  getAssets(): void {
    this.assetsService.getAssets().subscribe(
      assets => {
        this.assets = assets;
        this.dataSource = new MatTableDataSource<Asset>(this.assets);
      }
    );
  }

  sortData(event): void {
    this.assetsQueryService.setSorts(event);
    this.getAssets();
  }

  removeFilters() {
    this.sort.active = 'comp_name_sort';
    this.sort.direction = 'asc';
    this.sort.sortChange.emit({active: 'comp_name_sort', direction: 'asc'});
    this.assetsQueryService.removeFilters();
    this.getAssets();
  }

}

The sorting column and direction are passed to the assetsService because sorting is done in the backend (because of server-side pagination, not shown here). This is all working well, also with the reset button. The only problem is the displayed arrow.
So in summary, how do I reset the sorting arrow that is displayed in the table to it’s initial state programmatically?

Any help would be appreciated.

Solution

For anyone else looking for an answer for this particular problem. As ericbea pointed out in the comments, Angular is aware of this problem and an issue is still open on github about this: https://github.com/angular/components/issues/10242.
The only workaround that I found that worked for me is also listed there. It’s something like this:

this.sort.sort({ id: null, start: 'desc', disableClear: false });
this.sort.sort({ id: 'comp_name_sort', start: 'asc', disableClear: false });
(this.sort.sortables.get('comp_name_sort') as MatSortHeader)._setAnimationTransitionState({ toState: 'active' });

The first line is used to clear the sort in case the column you want the sort to is currently the active column.

Answered By – Emmy

Answer Checked By – Pedro (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.