0

I've read through I don't know how many examples and to my knowledge I'm following the example correctly but the columns do not update when I click on a header.

-I have included MatSortModule in my app.module.ts

-I have included matSort on the mat-table

-I have included mat-sort-header on header-cells of the columns I want to be able to sort by (all of them)

-I have included @ViewChild(MatSort) sort: MatSort; and the corresponding

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
  }

I don't see what else is left. Here is my code snippet:

<mat-table #table [dataSource]="dataSource" matSort class="dataTable">

    <!-- Name Column -->
    <ng-container matColumnDef="name">
        <mat-header-cell 
            *matHeaderCellDef 
            fxLayout="row" 
            fxLayoutAlign="start center" 
            mat-sort-header
            class="clickable"
        > 
            Product Name 
        </mat-header-cell>

        <mat-cell 
            *matCellDef="let item" 
            class="table-cell-content"
        > 
            {{item.name}} 
        </mat-cell>
    </ng-container>

...

defaultData: Array<Object> = null;
dataSource = new MatTableDataSource(this.defaultData);

@ViewChild(MatSort) sort: MatSort;

constructor(private getDataService: GetDataService) { 
  this.getDataService.getData()
    .subscribe(data => {
      this.defaultData = data;
      this.dataSource.data = this.defaultData;
    },
    err => console.log(err));
}

...

ngAfterViewInit() {
  this.dataSource.sort = this.sort;
}
2
  • 1
    Out of curiosity, is this the only table on this component? There is a weird way you have to do it if there are multiple tables within the same component. Commented Mar 14, 2018 at 17:20
  • Yes it is the only table. What looks weird? Commented Mar 14, 2018 at 17:21

3 Answers 3

0

The only thing I can think of that might be your issue here is that you probably shouldn't be assigning the data directly to the .data property of the .dataSource property. It is possible that modifying this property directly is causing the sort to not understand which data it is supposed to be working on in the first place, but I can't say that for sure (just taking a shot in the dark here). Creating a new MatTableDataSource() reference should trigger the reactivity of the Observable sequences that are built into the CDK Table structures, which should allow for the sorting to happen.

constructor(private getDataService: GetDataService) { 
  this.getDataService.getData()
    .subscribe(data => {
      // Your code:
      // this.defaultData = data;
      // this.dataSource.data = this.defaultData;
      
      // What I would do:
      this.defaultData = data;
      this.dataSource = new MatTableDataSource(data);
    },
    err => console.log(err));
}

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

Comments

0

you can sort the data with underscorejs and the material table will be refreshed or create a new instance with the MatTableDataSource.

this.myDataSource = _.sortBy(initialData, 'fieldToSort' );

or

this.myDataSource = new MatTableDataSource(initialData);

Comments

0

For me, even though I declared

dataSource: MatTableDataSource<MyRowEntity>

I was still setting it to an array (which would require an explicit call to matTableChild.renderRows())

// renderRows not called automatically onSortChange
dataSource = [{name: 'hello'}, {name: 'world'}] 

Solution:

// renderRows called automatically onSortChange
this.dataSource = new MatTableDataSource(myRowEntities); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.