Check out our Angular Book Series.

How do I sort two ng-material table instances on the same component?

I have been doing some prototype work with the ng-material's table component. The table component is, basically, a DataGrid.

As part of this proof of concept work I put two separate tables inside the same ecomponent. The code worked well enough, but I had trouble getting both tables to sort.

To get a table to sort you need to add a ViewChild reference to the MatSort. In the HTML:


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

Then you get a reference inside the component code:


@ViewChild(MatSort) sort: MatSort;

And attach the two together:


ngOnInit() {
this.rowData1.sort = this.sort;
}

The my missing magic from last week's post.

There is a problem once you add a second table. First create the two tables:


<table mat-table [dataSource]="rowData1" matSort >
</table>
<table mat-table [dataSource]="rowData2" matSort >
</table>

Then get the ViewChildren:


@ViewChild(MatSort) sort: MatSort;

@ViewChild(MatSort) sort2: MatSort;

This will cause issues, because both variables are pulling the same MatSort value and only the first grid will sort.

The way to solve this is how you mark the table to get the matSort value:


<table mat-table [dataSource]="rowData1" matSort #sort1="matSort">
</table>
<table mat-table [dataSource]="rowData2" matSort #sort2="matSort">
</table>

Now get the ViewChildren references like this:


@ViewChild('sort1') sort: MatSort;

@ViewChild('sort2') sort2: MatSort;

And associate the sort element with the data source:


ngOnInit() {
this.rowData1.sort = this.sort1;
this.rowData2.sort = this.sort2;
}

Now both grids should sort properly.

Five Reasons My ngMaterial Table won't sort!

I've been doing some prototype work with the ngMaterial grid and had a problem where the grid would not sort. Here are a few things to check if this happens to you.

  1. Import the MatSortModule Module: Be sure that your @NgModule definition includes the MatSortModule:


    @NgModule({
    declarations: [
    AppComponent,
    ],
    imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatTableModule,
    MatSortModule,
    ],
    bootstrap: [AppComponent]
    })

    Without this, the sorting will not work.

  2. Specify the matSort header: Be sure to specify the matSort header on your table grid:


    <table mat-table [dataSource]="rowData" matSort class="mat-elevation-z8"
    >

    // rest of the table definition here
    </table>

    Without that you won't be able to click on the headers.

  3. Wrap Your Data Source in a MatTableDataSource: If you do not wrap your own datasource--probably an array--in the MatTableDataSource class you'll have to write your own sorting algorithm to affect your data because it won't work out of the box.


    this.rowData = new MatTableDataSource(myRowDataArray);

    Do this because it makes your life easier.

  4. Tell the data source about your sort: Your MatTableDataSource does not know about the sort by default. Get a ViewChild instance to the sort in your code:


    @ViewChild(MatSort) sort: MatSort;

    And apply that:


    ngOnInit() {
    this.rowData.sort = this.sort;
    }

    Hopefully you got this far and your table is sorting now.

  5. Write Your Own Sort: If you're avoiding using the MatTableDataSource for some reason, you'll have to write your own sort algorithm. In the HTML, listen for the matSortChange event:


    <table mat-table [dataSource]="rowData" matSort class="mat-elevation-z8" (matSortChange)="onMatSortChange()">
    // rest of the table definition here
    </table>

    And in your code:


    onMatSortChange(){
    // do something to modify your data source here.
    }

I've found the documentation lacking for ngMaterial, but so far we plan on plunging ahead with it. Hopefully this helped someone out.

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.