1

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

DEMO

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.

User123
  • 343
  • 2
  • 7
  • 22
  • Possible duplicate of [How to sort two nested objects?](https://stackoverflow.com/questions/37206442/how-to-sort-two-nested-objects) – Randy Casburn Jan 14 '19 at 00:52
  • In the example, you have mentioned JSON has only an array value, in my case, it has an object as well as an array. – User123 Jan 14 '19 at 01:08

0 Answers0