0

Using an Angular Material Design table, I'm simply trying to sort the headers of two columns in a data table. (They are the Employee Name and Job Title columns in the code below.) Both aren't sorting. Not sure why. Here's my code and thanks, CM

employee-table.component.html

<div>

  <mat-table [dataSource] = "dataSource" matSort>
    <ng-container matColumnDef="photo">
      <mat-header-cell *matHeaderCellDef>Profile</mat-header-cell>
      <mat-cell *matCellDef="let employee"><img width = "100" height = "100" src = "../assets/images/{{employee.username}}.jpg" >
      </mat-cell>
    </ng-container>

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


    <ng-container matColumnDef="position">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Job Title</mat-header-cell>
      <mat-cell *matCellDef="let employee">{{employee.position}}</mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns" color="primary"></mat-header-row>
    <mat-row *matRowDef="let row; columns:displayedColumns"></mat-row>

  </mat-table>
</div>

employee-table.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {MatSort, MatSortable, MatTableDataSource} from '@angular/material';
import {EmployeeService} from '../employee.service';

@Component({
  selector: 'app-employee-table',
  templateUrl: './employee-table.component.html',
  styleUrls: ['./employee-table.component.css']
})
export class EmployeeTableComponent implements OnInit {
  @ViewChild(MatSort) sort: MatSort;
  dataSource;
  displayedColumns = ['photo', 'name', 'position'];

  constructor() { }
  ngOnInit() {   
    this.dataSource =[
            {
              "id": 1,
              "name": "Leanne Grahamz",
              "username": "Bret",
              "position": "Software Developer"
            },
            {
              "id": 2,
              "name": "Ervin Howell",
              "username": "Antonette",
              "position": "Graphic Designer"
            },
            {
              "id": 3,
              "name": "Clementine Bauch",
              "username": "Samantha",
              "position": "Front End Developer"
            },
            {
              "id": 4,
              "name": "Patricia Lebsack",
              "username": "Karianne",
              "position": "Full Stack Developer"
            },
            {
              "id": 5,
              "name": "Chelsey Dietrich",
              "username": "Kamren",
              "position": "Database Administrator" 
            }
    ]; //End data object

    this.dataSource.sort = this.sort;

  }//End ng onInit

}//End class EmployeeTableComponent
1
  • What else would you like to see Parth Godhani? I will gladly edit my post. Commented Apr 27, 2018 at 12:53

2 Answers 2

1

You are setting the datasource sort this.dataSource.sort = this.sort; too early in the lifecycle. As suggested by the material.angular.io examples, you should set the datasource sort after the view init :

Copied from the material.angular.io example :

 /**
   * Set the sort after the view init since this component will
   * be able to query its view for the initialized sort.
   */
  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
  }

You should also edit your datasource initialisation :

ngOnInit() {
 this.dataSource = new MatTableDataSource([{
     "id": 1,
     "name": "Leanne Grahamz",
     "username": "Bret",
     "position": "Software Developer"
    }, 
    ...
    {
     "id": 5,
     "name": "Chelsey Dietrich",
     "username": "Kamren",
     "position": "Database Administrator"
    }
   ]);
}

Here is an edit of the initial example with your code.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks ibenjelloun for responding. I thought it might have something to do with that line sorting the data source. So should I remove that line from ngOnInit and place the call to ngAfterView with that line in it just after ngOnInit?
The sort is the only line required to be in the ngAfterViewInit as you are calling the this.sort which is initialized by the template. I didn't see it before but you also need to specify datasource as MatTableDataSource. What you are calling datasource in your code is actually the ELEMENT_DATA in the angular material example.
If you have a moment could you edit your answer to show me what you're talking about looks like in code?
Thank you very much for taking the time to show me how to do this. My table is sorting now. And I understand the changes you made. So grateful for this forum and all that take the time to share their expertise so that there will be other experts in the world...
1

Alternatively, you could also use a timeout for your sorting (and pagination if needed), for example:

setTimeout(() => {
  this.tableDataSource.sort = this.sort;
  this.tableDataSource.paginator = this.paginator;
}, 0);

2 Comments

I don't think that setting a timeout without any value for time will help here.
You're right, i forgot to set the value (edited now). 0 is enough since we just want to move it to the end of the event queue.