Reputation: 51
I'm trying to write sorting pipe according to code in this link: http://www.advancesharp.com/blog/1211/angular-2-search-and-sort-with-ngfor-repeater-with-example Although I have trouble with dealing with undefined values. My pipe works correctly on columns where there are not any undefined values. But when there is at least one undefined value in column pipe work in a strange way. My code below:
html template:
*ngFor="let candidate of filteredList | orderBy:{property: column, direction: direction}"
in html template to choose column and direction eg:
<th class="pointer" nowrap="nowrap" (click)="sort('lastName')">{{ 'candidates.candidates' | translate }}
<i class="fa" [ngClass]="{'fa-sort': column != 'lastName',
'fa-sort-asc': (column == 'lastName' && !isDesc),
'fa-sort-desc': (column == 'lastName' && isDesc) }"
aria-hidden="true"> </i></th>
order-by.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {
transform(candidates: Array<object>, args?: any): any {
candidates = candidates || [];
return candidates.sort(function (a, b) {
if (a[args.property] === b[args.property]) {
return 0;
}
if (a[args.property] === '' || a[args.property] === null || typeof a[args.property] === 'undefined') {
return 1;
}
if (b[args.property] === '' || b[args.property] === null || typeof b[args.property] === 'undefined') {
return -1;
}
if (a[args.property] < b[args.property]) {
console.log(a[args.property] + ' wartosc property');
return -1 * args.direction;
} else if (a[args.property].toLowerCase() > b[args.property].toLowerCase()) {
return 1 * args.direction;
} else {
return 0;
}
});
}
}
component.ts:
public sort(property: string) {
this.isDesc = !this.isDesc;
this.column = property;
this.direction = this.isDesc ? 1 : -1;
}
I was trying many different approaches but none of then was worinkg fine.
Upvotes: 4
Views: 11284
Reputation: 22743
It will work even for null
, undefined
''
and any type of data type like number string bool:
transform(arr: any[], property: any, direction: number): any[] | null {
if(!arr || arr?.length == 0)
return arr;
arr.sort((a: any, b: any) => {
let v1 = a[property]?? '';
let v2 = b[property]?? '';
if(v1 < v2)
return 1 * direction;
else if(v1 > v2)
return -1 * direction;
else
return 0 * direction;
});
return arr;
}
Upvotes: 0
Reputation: 295
Maybe that's because JavaSctipt Array.sort
function will always put undefined to the end of array and the undefined values aren't passed to compareFunction as a and b arguments.
See this post for more details: javascript array.sort with undefined values
Upvotes: 0
Reputation: 151
Can you use lodash for sorting?
import { Pipe, PipeTransform } from '@angular/core';
import * as _ from 'lodash';
@Pipe({
name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {
transform(array: Array<{}>, args: string[]): Array<string> | Array<{}> {
array = array || [];
if (typeof args === 'undefined' || args.length !== 2) {
return array;
}
const [key, direction] = args;
if (direction !== 'ASC' && direction !== 'DESC') {
return array;
}
return _.orderBy(array, (item:any) => item[key], direction.toLowerCase());
}
}
Upvotes: 0