Angular Material Table doesnt show sorted table

791 Views Asked by At

earthlings! I am desperately trying to get sorting to work on my mat table. At first I thought that it didn't work at all, however using

<table mat-table matSort (matSortChange)="sortData($event)" [dataSource]="source" class="mat-elevation-z8">

and

sortData(event: any){
   this.dataSource.sort = this.sort;
   console.log(this.dataSource.sortData(this.dataSource.data, this.sort));
   this.dataSource.sortingDataAccessor
}

I am able to determine that sorting works (via console log), however my table displayed stays the same

enter image description here

Background: I am using a json server npm package and displaying the data (from subscription) in a mat-table. I am quite positive it has something to do with the subscription of the data (it not being avilable outright). However there are no data refreshes happening (logging refreshes as well):

loadData() {
    this.dataService.getAllData().subscribe((response: any) => {
     this.data = response;
     this.dataSource = new MatTableDataSource<IData>(this.data);
     this.dataSource.sort = this.sort;
     console.log('getting Data');
   });
}

I'm not sure how would I go about setting up a stackblitz for such a scenario.

I have knocked down some usual suspects - MatSortModule is imported in app module, MatColumnDef"xxx" matches data column name "xxx".

Any help would be great or if there are some other code snippets i could show.

2

There are 2 best solutions below

4
vaira On

Set initially as an empty array in property declaration

public dataSource = new MatTableDataSource<IData>([]);

Now you will never reset dataSource by new MatTableDataSource. Only use its dataSource.data property to set it up.

loadData() {
    this.dataService.getAllData().subscribe((response: any) => {
      this.data = response;
      this.dataSource.data = this.data;
    });
  }
0
Eliseo On

when you use a MatTableDataSource(*) with sort you:

1.-use ViewChild to get the "sort"

@ViewChild(MatSort) sort: MatSort;

2.-assing the sort after create the dataSource and when the table is visible.

 this.dataSource=new MatTableDataSource(data)
 this.dataSource.sort=this.sort

The second condition means that, if we are using a service to get the data we need equal inside subscribe

 this.myService.getData().subscribe((res:any)=>{
    this.dataSource=new MatTableDataSource(res)
    this.dataSource.sort=this.sort
 }

BUT also means that if we has in .html some like

  <div *ngIf="dataSource" else loading>
     <table mat-table>...</table>
  </div>
  <ng-template #loading>
    loading...
  </ng-template>

We need Angular give a change to display the data (usign a setTimeout), and after assing the sort

 this.myService.getData().subscribe((res:any)=>{
    this.dataSource=new MatTableDataSource(res)
    seTimeout(()=>{
       this.dataSource.sort=this.sort
    })
 }

(*)And what about you don't use a MatTableDataSource?, remember that a dataSource can be a MatTableDataSource or an Array (or and observable with pipe async). in this case (and only in this case) is when we use the event (matSortChange). Well, also, if we want use a custom sort we use the event.

In this case we change directly the datasource (the array)