I used angular custom pipe to sort my table rows, but if the object is nested inside another object, my pipe doesn't work. How do I fix the issue and also make it reusable for different arrays as I have many cases like this in my project.
I've written my custom pipe using this logic Ascending and Descending Sort in Angular 4. Right now, when I click User, I can sort it alphabetically, I'd like achieve the same when I click address and category and avoid line 11(in demo) as I can reuse it in different scenarios
Component
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
isDesc: any;
column: any;
direction: any;
orders = [{
user: {
name: 'John',
address: {
zipcode: '75028',
state: 'AZ',
},
categories: [{
category: { id: 8, name: "associate" }
}]
},
},
{
user: {
name: 'Jessice',
address: {
zipcode: '76800',
state: 'TX',
},
categories: [{
category: { id: 8, name: "Manager" }
}]
}
}]
sort(property) {
this.isDesc = !this.isDesc; //change the direction
this.column = property;
this.direction = this.isDesc ? 1 : -1;
console.log(property);
};
}
HTML:
<table>
<thead>
<th (click)="sort('user_name')">User <i class="fa" [ngClass]="{'fa-sort':
column != 'user_name','fa-sort-asc': (column == 'user_name' &&
isDesc),'fa-sort-desc': (column == 'user_name'
&& !isDesc) }"
aria-hidden="true">
</i>
</th>
<th (click)="sort('address_zipcode')"> Address <i class="fa"
[ngClass]=" {'fa-sort': column != 'address_zipcode', 'fa-sort-asc':
(column == 'address_zipcode' && isDesc), 'fa-sort-desc': (column
'address_zipcode' && !isDesc) }" aria-hidden="true">
</i>
</th>
<th> Category </th>
</thead>
<tbody>
<tr *ngFor="let data of orders | orderBy: {property: column, direction:
direction}">
<td>{{data.user.name}}</td>
<td>{{data.user.address.zipcode }}</td>
<td><span *ngFor="let cat of data.user.categories">
{{cat.category.name}} </span></td>
</tr>
Custom Pipe
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {
transform(records: Array<any>, args?: any): any {
if(records && records.length >0 ){
records.map(record => record['user_name'] = record.user.name);
// records.map (record => record['address_zipcode'] =
// record.user.address.zipcode)
return records.sort(function(a, b){
if(a[args.property] < b[args.property]){
return -1 * args.direction;
}
else if( a[args.property] > b[args.property]){
return 1 * args.direction;
}
else{
return 0;
}
});
}
};
}
I expect my custom pipe to sort nested objects and make it reusable.