Adding Advanced Sorting to the Angular Data Table

Welcome Back to Our Angular Journey

Pathakrajaryan
3 min readNov 29, 2023

Introduction to Sorting

In the previous article, we successfully integrated pagination into our generic-data-table. Now, we elevate its functionality by implementing sorting. Sorting is not just a feature; it's a necessity for users who need to navigate through data intuitively. In this segment, we'll explore how we brought this crucial feature to life in our Angular data table.

1. Setting Up Sorting Inputs

We begin by enhancing our generic-data-table component with crucial @Input() properties:

@Input() isServerSideSorting: boolean = true;

Note: Before proceeding, import below modules

import { MatPaginatorModule } from '@angular/material/paginator';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

2 Implementing Sorting in HTML

Firstly, we modified our table headers to include sorting capabilities. This is done by adding Angular Material’s mat-sort-header the directive in each header and adding matSort directive in the table tag itself.

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" matSort>
<ng-container *ngFor="let column of columns; let i = index" [matColumnDef]="column.field">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ column.label }}
</th>
<td mat-cell *matCellDef="let element" [style.width.%]="column.width">{{ element[column.field] }}</td>
</ng-container>
</table>

3 The TypeScript Logic: Handling Sorting Events

For sorting functionality, we introduced sortTable();in generic-data-table. This gets triggered when a user alters the sorting criteria, handling both client-side and server-side sorting scenarios

We start by declaring a MatSort view child and an @Output() event emitter for sorting changes:

@ViewChild(MatSort) sort: MatSort;
@Output() sortChanged = new EventEmitter<{ property: string, direction: string } | null>();
  • MatSort is a directive that manages the sorting state and decision-making process for the table.
  • sortChanged is an event emitter that communicates the sorting criteria back to a parent component, especially useful for server-side sorting scenarios
sortTable() {
this.sort.sortChange.subscribe((event) => {
if (this.isServerSideSorting) {
// Emit parameters for server-side sorting
let sortParam = null;
if (event.direction === 'asc' || event.direction === 'desc') {
sortParam = { property: event.active, direction: event.direction.toUpperCase() };
}
this.sortChanged.emit(sortParam);
} else {
// Handle client-side sorting
this.clientSideSorting(event.active, event.direction);
}
});
}

This method determines whether to handle sorting on the client side or to emit the sorting parameters for server-side processing.

How It Functions

  • Server-Side Sorting: When the table is set for server-side sorting, sortTable listens for changes and emits the sortChanged event with the appropriate parameters. This notifies the parent component about the user's chosen sorting criteria, prompting it to fetch or rearrange data accordingly.
  • Client-Side Sorting: In scenarios where the data resides on the client side, sortTable takes a direct approach. It calls the clientSideSorting function, which rearranges the displayed data based on the selected column and sort direction.

Client-Side Sorting Logic

For client-side scenarios, the clientSideSorting function arranges the data based on the chosen column and direction:

const sortedData = this.dataSource.slice().sort((a, b) => {
let valueA = a[columnName];
let valueB = b[columnName];

// Assuming string sorting, include your own for numbers, dates, etc.
let comparison = 0;
if (valueA > valueB) {
comparison = 1;
} else if (valueA < valueB) {
comparison = -1;
}
return direction === 'asc' ? comparison : -comparison;
});
this.dataSource = sortedData;

Integrating Sorting in the Parent Component

Just like with pagination, the parent component plays a crucial role in handling sorting, especially in server-side scenarios. The sortChanged event is captured by the parent, which then fetches or rearranges the data based on the new sorting parameters.

 <app-generic-data-table 
[dataSource]="dataSource"
[columns]="columns"
[totalItems]="totalItemCount"
[isServerSidePagination]="false"
[isServerSideSorting]="false"
(pageChanged)="pageChanged($event.pageIndex, $event.pageSize)"
(sortChanged)="onSortChanged($event)">
</app-generic-data-table>

Conclusion: A Table That Listens and Reacts

With sorting integrated, our generic-data-table isn't just displaying data; it's providing a dynamic interface for users to interact with and organize information effectively. This makes our table not just a tool but a smart component that enhances the overall user experience.

Stay tuned as we continue to refine our data table with more features, ensuring it remains a versatile and essential component in any Angular application.

--

--