Angular: How to Custom Sort MatTable Columns

Thursday Apr 29th 2021 by Rob Gravelle

Learn how to custom sort MatTable columns in Angular inside this web development and programming tutorial.

Implementing Custom Sorting on MatTable Columns

I couldn't count the number of tables that I've worked on that required at least one sortable column. It's the kind of thing that users love, perhaps because it gives them tremendous control over their data. In the early days of the Web, I used JavaScript to implement custom sorting. Now, many third-party widgets have sorting capabilities baked in. In this regard, Angular is no exception. The Material Data Table, or MatTable, is chock-full of features, including pagination, sorting, filtering, to name but a few. This tutorial will describe how to give your users the ability to sort table columns using the MatTable's built-in sorting mechanism.

Demo Preview

Some readers may be unaware that I am also a professional musician and recording artist. To combine my two passions, I created a table to track some of my digital release singles. Here's a screen capture of the finished demo:

Custom Sorting MatTable Columns with Angular

As you can see, it contains five columns - all but the Thumb column are sortable. The current sort is indicated by an arrow to the right of the column header. By default, columns appear in the same order as in the underlying data source. I would like to sort table rows by Release Date in descending order so that the most recent release appears at the top of the table, as they appear in the above screenshot. We'll go over how to do that in the next section.

Editor's Note: We discussed how to customize the appearance of Mat-Select Text in a previous article.

Setting the Initial Sort

The first step is to make table columns sortable. To do that, import the MatSort directive and add mat-sort-header to each column header cell that should trigger sorting:

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

MatSort is a container for MatSortables to manage the sort state and provide default sort parameters. We can reference it using the @ViewChild Property Decorator to access its properties. The initial sort is set in our table class's OnInit hook:

import {Component, OnInit, ViewChild} from '@angular/core';
import {MatTableDataSource, MatSort, Sort} from '@angular/material';

export class TableSortingExample implements OnInit {
  public displayedColumns = [
  public dataSource = new MatTableDataSource(RELEASES);
  @ViewChild(MatSort) private sort: MatSort;

  ngOnInit() {
    this.dataSource.sort = this.sort;

    const sortState: Sort = {
      active: 'releaseDate', 
      direction: 'desc'
    this.sort.active = sortState.active;
    this.sort.direction = sortState.direction;

Making a MatTable Column Sortable with Angular

Once you've added sorting capability to your table using the instructions above, all you have to do to designate a column as sortable is add the mat-sort-header directive to the <mat-header-cell> element in the template. Here's the name column:

<!-- name Column -->
<ng-container matColumnDef="name">
  <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
  <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>

Advanced Sorting

The MatTableDataSource sorts with the assumption that the sorted column's name matches the data property name that the column displays. If the data properties do not match the column names, or if a more complex data property accessor is required, you can employ a custom sortingDataAccessor function to override the default data accessor on the MatTableDataSource. Here's an example that sorts a date column where a string was used instead of a Date type:

ngAfterViewInit() {
  this.dataSource.sortingDataAccessor = (item, property) => {
    switch (property) {
      case 'date': {
        return new Date(item.date);
      default: {
        return item[property];

If you are not using the MatTableDataSource, but instead are providing a data array directly to the table, you can listen to the sort's matSortChange event and re-order your data according to the sort state. Afterward, you may have to invoke renderRows() on the table since it will not automatically check the array for changes. Here's a table that contains nutritional information of deserts that uses the matSortChange hook to sort on the Carbs column:

<table matSort (matSortChange)="sortData($event)" matSortActive="carbs" matSortDirection="asc">

The sortData() function handles all of the sorting for the table:

public sortData(sort: Sort) {
  const data = this.desserts.slice();
  if (!sort.active || sort.direction === '') {
    this.sortedData = data;

  this.sortedData = data.sort((a, b) => {
    const isAsc = sort.direction === 'asc';
    switch (sort.active) {
      case 'name': return compare(a.name, b.name, isAsc);
      case 'calories': return compare(a.calories, b.calories, isAsc);
      case 'fat': return compare(a.fat, b.fat, isAsc);
      case 'carbs': return compare(a.carbs, b.carbs, isAsc);
      case 'protein': return compare(a.protein, b.protein, isAsc);
      default: return 0;

function compare(a: number | string, b: number | string, isAsc: boolean) {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);


In this tutorial, we learned how to give your users the ability to sort table columns using the MatTable's built-in sorting mechanism.

Rob Gravelle resides in Ottawa, Canada, and has been an IT guru for over 20 years. In that time, Rob has built systems for intelligence-related organizations such as Canada Border Services and various commercial businesses. In his spare time, Rob has become an accomplished music artist with several CDs and digital releases to his credit.

Mobile Site | Full Site