-
-
Save mdmoin7/13828acc95b3bf6c32eb98b9e7a6c581 to your computer and use it in GitHub Desktop.
| /* | |
| *ngFor="let c of oneDimArray | sortBy:true/false:'asc'" | |
| *ngFor="let c of arrayOfObjects | sortBy:true/false:'asc':'propertyName'" | |
| */ | |
| import { Pipe, PipeTransform } from "@angular/core"; | |
| import { orderBy, sortBy } from "lodash"; | |
| @Pipe({ name: "sortBy" }) | |
| export class SortByPipe implements PipeTransform { | |
| transform<T>( | |
| value: T[], | |
| caseInsensitive = false, | |
| order = "", | |
| column: string = "" | |
| ): T[] { | |
| if (!value || order === "" || !order) { | |
| return value; | |
| } // no array | |
| if (!column || column === "") { | |
| const sorted = this.sortOnCaseSensitivity(value, caseInsensitive); | |
| if (order === "asc") { | |
| return sorted; | |
| } else { | |
| return sorted.reverse(); | |
| } | |
| } // sort 1d array | |
| if (value.length <= 1) { | |
| return value; | |
| } // array with only one item | |
| else { | |
| const converted = this.convertMultiOnCaseSensitivity( | |
| value, | |
| column, | |
| caseInsensitive | |
| ); | |
| return orderBy(converted, ["sortCol"], [order]).map(v => { | |
| delete v["sortCol"]; | |
| return v; | |
| }); | |
| } | |
| } | |
| sortOnCaseSensitivity<T>(value: T[], caseInsensitive: boolean): T[] { | |
| return sortBy(value, (v: T) => { | |
| if (typeof v === "string" && caseInsensitive) { | |
| return v.toLowerCase(); | |
| } | |
| return v; | |
| }); | |
| } | |
| convertMultiOnCaseSensitivity<T>( | |
| value: T[], | |
| column: string, | |
| caseInsensitive: boolean | |
| ): T[] { | |
| let converted = value.map((v: T) => ({ ...v, sortCol: v[column] })); | |
| if (caseInsensitive) { | |
| converted = value.map((v: T) => { | |
| if (typeof v[column] === "string") { | |
| return { ...v, sortCol: v[column].toLowerCase() }; | |
| } | |
| return { ...v, sortCol: v[column] }; | |
| }); | |
| } | |
| return converted; | |
| } | |
| } |
hey @mdmoin7, I went ahead and forked your gist and made some changes to fix the issue regarding no sort when caseInsensitive = false. I have also changed the code to import lodash-es, as latest Angular warns against using CommonJS or AMD modules - they prefer es modules
If you pass
caseInsensitiveasfalse, it will not sortvalue-'sortCol'will not be defined in that case and will just be ignored.
@gcko can you help me with the usage Syntax as well so that I can also understand the exact behavior here and its problem and thanks for the fork.
Sure, lets look at the following sections of code:
First, the call to this.convertMultiOnCaseSensitivity
else{
const converted=this.convertMultiOnCaseSensitivity(value,column,caseInsensitive);
return orderBy(converted, ['sortCol'], [order]).map(v=>{
delete v['sortCol'];
return v;
});
}And the function that it calls:
convertMultiOnCaseSensitivity(value:any[],column,caseInsensitive){
let converted=value;
if(caseInsensitive){
converted=value.map(v=>{
if(typeof v[column]==='string'){
return {...v,sortCol:v[column].toLowerCase()}
}
return v;
})
}
return converted;
}The key part is that sortCol will only be added if caseInsensitive is a falsey value. That means when caseInsensitive = true, in the call to orderBy, (orderBy(converted, ['sortCol'], [order]), the items in converted do not have a sortItem key.
@gcko thanks for the clarity, what i think here seems to be a problem when user doesn't provide sorting column name, correct me if I'm wrong. So in that case does placing sensitivity argument last in sequence to pipe help!!
@mdmoin7 No, the issue is the same whether or not the user passes a value to caseInsensitivity. You can confirm this because the caseInsensitivity is initialized as false, so unless you pass a value of true, it will be false.
The issue is not related to whether the user provides a sorting column name, to be clear.
For example, the issue will appear if you do the following call:
*ngFor="let item of items|sortBy:false:'asc':'keyToSortOn';
If you pass
caseInsensitiveasfalse, it will not sortvalue-'sortCol'will not be defined in that case and will just be ignored.