3

Im using mat table with sorting, where I want to set default sorting on a certain column.

This works for plain attributes but not for nested ones.

Here is my table

<table mat-table [dataSource]="dataSource" multiTemplateDataRows 
       matSort matSortActive="break" matSortDirection="asc"
       class="mat-elevation-z4 w-100">

My nested sorting

this.dataSource.sort = this.sort;
   this.dataSource.sortingDataAccessor = (item, property) => {
   switch(property) {
      case 'break': return item.break.start;
      default: return item[property];
   }
};

Also this nested sorting is fine, when you are manually clicking on the header to sort, it does what I expect but on default it doesn't sort, only shows the sorting arrow.

That's how it looks like on page load:

Here is the corresponding stackblitz.

2
  • this may help or you can add stackblitz demo if problem still presist Commented Oct 10, 2019 at 12:16
  • Unfortunately, this solution does not work for nested objects. Commented Oct 10, 2019 at 12:21

3 Answers 3

2

The initial sorting didn't work properly when i researched it in may.

In my case it was necessary to write my own setSortHeader function that executes after getting data.

setSortHeader() {
  this.sort.active = 'break';
  this.sort.direction = 'desc';
  this.sort.sortChange.emit({ active: this.sort.active, direction: this.sort.direction });

  const sortHeader = this.sort.sortables.get('break');
  if (sortHeader) sortHeader['_setAnimationTransitionState']({ toState: 'active' });
}

I'm not sure that this code still necessary but in my case that worked.

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

Comments

1
<ng-container matColumnDef="firstName">
    <th mat-header-cell class="mat-header-sticky" id="firstName" *matHeaderCellDef mat-sort-header tabindex="0"
      [attr.aria-label]="'First Name Tool Tip'" [matTooltip]="tooltipConfiguration['firstName']"
      [matTooltipPosition]="'above'" [matTooltipClass]="'matTooltip-panel'">
      First Name
    </th>
    <td mat-cell *matCellDef="let contact" class="align-center">
      <span class="display-block overflow-ellipsis">
        {{ contact.firstName }}
      </span>
    </td>
</ng-container>

Just use same matColumnDef="firstName" and {{ contact.firstName }} notice that the property .firstName is matching with matColumnDef ID. This is as per angular docs.

Comments

0

Please try the below.


If you want to change the default direction, change it on the ngOnInit method call to this.sortItem

// app.component.ts

import { Component, ViewChild } from '@angular/core';

import { Sort, MatSort, MatPaginator } from '@angular/material';

import { interval } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public displayedColumns: string[] = ['name', 'break',];

  public sortedData: any;

  constructor( ) { }

  ngOnInit() {
    setTimeout(() => {         
      this.sortItem({ active: 'break', direction: 'asc' });
    }, 1000);
  }
  compare(a: number | string, b: number | string, isAsc: boolean) {
    return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
  }

  sortItem(sort: Sort) {
    const data = DATA_SOURCE.slice();
    if (!sort.active || sort.direction === '') {
      this.sortedData = data;
      return;
    }

    this.sortedData = data.sort((a, b) => {
      const isAsc = sort.direction === 'asc';
      switch (sort.active) {
        case 'break': return this.compare(a.breakTime.start, b.breakTime.start, isAsc);        
        default: return 0;
      }
    });
  }
}

const DATA_SOURCE = [
  {
    name: 'Alice',
    breakTime: {
      start: '14-00',
      end: '14-00'
    },
  },
  {
    name: 'Steve',
    breakTime: {
      start: '10-00',
      end: '11-00'
    },
  },
  {
    name: 'Bob',
    breakTime: {
      start: '12-00',
      end: '13-00'
    },
  },
];

// app.component.html

<table mat-table [dataSource]="sortedData" multiTemplateDataRows 
       matSort (matSortChange)="sortItem($event)" 
       class="mat-elevation-z4 w-100">

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef> Name </th>
    <td mat-cell *matCellDef="let item"> {{item.name}} </td>
  </ng-container>

  <ng-container matColumnDef="break">
    <th mat-header-cell *matHeaderCellDef mat-sort-header > Break </th>
    <td mat-cell *matCellDef="let element">
      {{element.breakTime.start}} - {{element.breakTime.end}}
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let element; columns: displayedColumns;"
      class="element-row"
      [class.example-expanded-row]="expandedElement === element"
      (click)="expandedElement = expandedElement === element ? null : element">
  </tr>
</table>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.