user636312
user636312

Reputation: 153

angular 5 , orderBy asc/desc

Is there an option to change sorting by asc/desc in orderBy pipe?

The array:

this.testArr = [{name: 'bbb', id: '1'}, {name: 'ccc', id: '2'}, {name: 'aaa', id: '0'}];

In HTML:

<ul><li *ngFor="let item of testArr | orderBy: 'id' : true"><div>{{item.id}}</div></li></ul>

Replacing the 'true' to 'false'/'asc'/'desc' did not work. The required output should be: 0, 1, 2 and by the other parameter: 2, 1, 0.

Thank you.

Upvotes: 3

Views: 18943

Answers (2)

Vignesh
Vignesh

Reputation: 2386

Try this code: You can create a custom pipe for sorting:

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({
    name: 'orderBy'
})
export class OrderBy{

 transform(array, orderBy, asc = true){

     if (!orderBy || orderBy.trim() == ""){
       return array;
     } 

     //ascending
     if (asc){
       return Array.from(array).sort((item1: any, item2: any) => { 
         return this.orderByComparator(item1[orderBy], item2[orderBy]);
       });
     }
     else{
       //not asc
       return Array.from(array).sort((item1: any, item2: any) => { 
         return this.orderByComparator(item2[orderBy], item1[orderBy]);
       });
     }

 }

 orderByComparator(a:any, b:any):number{

     if((isNaN(parseFloat(a)) || !isFinite(a)) || (isNaN(parseFloat(b)) || !isFinite(b))){
       //Isn't a number so lowercase the string to properly compare
       if(a.toLowerCase() < b.toLowerCase()) return -1;
       if(a.toLowerCase() > b.toLowerCase()) return 1;
     }
     else{
       //Parse strings as numbers to compare properly
       if(parseFloat(a) < parseFloat(b)) return -1;
       if(parseFloat(a) > parseFloat(b)) return 1;
      }

     return 0; //equal each other
 }
}

.component.ts

list = [
    {
        name:"Terry",
        age:23
    },
    {
        name:"Bob",
        age:25
    }
    {
        name:"Larry",
        age:27
    }
];

order = "age";
ascending = true;

.html

<div *ngFor="let person of list | orderBy:order:ascending">
    Name: {{person.name}}, Age: {{person.age}}
</div>

Upvotes: 5

Horse
Horse

Reputation: 3063

The angular guide recommends not using pipes due to performance and minification issues - https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe

The preferred method is to have a filter / sort method in the component

sortAccounts(prop: string) {
    const sorted = this.accounts.sort((a, b) => a[prop] > b[prop] ? 1 : a[prop] === b[prop] ? 0 : -1);
    // asc/desc
    if (prop.charAt(0) === '-') { sorted.reverse(); }
    return sorted;
}

Then in the component view

<li *ngFor="let a of sortAccounts('id')">

or

<li *ngFor="let a of sortAccounts('-id')">

Upvotes: 6

Related Questions