I'm developing an Angular2 app and I need to use a filter for some of my *ngFor
directives.
I created the following Pipe
:
import {Pipe, PipeTransform} from "@angular/core";
@Pipe({
name: 'filter',
pure: false
})
export class FilterPipe implements PipeTransform {
transform(array: Array<Object>, key: string, value: string, negate: boolean): Array<Object> {
if (array === null || array === undefined) {
return [];
} else {
if (negate) {
return array.filter(item => item[key] !== value);
} else {
return array.filter(item => item[key] === value);
}
}
}
}
Here is an example of how I use it:
<div class="item" *ngFor="let i of items | filter:'type':'S':true">
But it doesn't work if I would to filter for a child property.
With Angular v1.x I could apply the following filter:
item in array | filter: { type: {subtype: 'foo'}}
Do you know how can I reach the same with my Angular2 Pipe?
Thank you in advance.
developer033 :
You can do something like this:\n\nUse this or create your own method to extract deep(or even not deep properties):\n\ngetProperty(obj: any, path: string): string { \n if (obj == null || obj.constructor !== Object) {\n return undefined;\n }\n\n const replaced: string = path.replace(/\\[(\\w+)\\]/g, '.$1').replace(/^\\./, '');\n const keys: string[] = replaced.split('.');\n let result: string = obj[keys.shift()];\n\n for (const key of keys) {\n if (result == null || result.constructor !== Object) {\n return undefined;\n }\n\n result = result[key];\n }\n\n return result;\n}\n\n\nNow, you adjust your pipe to:\n\n@Pipe({\n name: 'filterBy',\n pure: false\n})\nexport class FilterByPipe implements PipeTransform {\n\n transform(items: any[], prop: string, term: string, exact: boolean = false): any[] {\n\n if (!Array.isArray(items) || typeof term !== 'string') {\n return items;\n }\n\n const strTerm: string = `${term}`.toLowerCase();\n\n return items.filter((obj: any) => {\n const value: string = this.getProperty(obj, prop);\n if (!value) {\n return false;\n }\n\n const strValue: string = `${value}`.toLowerCase(); \n return exact\n ? strTerm === strValue\n : strValue.indexOf(strTerm) !== -1;\n });\n }\n\n\nTo use it:\n\n<div *ngFor=\"let item of items | filterBy: 'nestedObj.key': search: exact\">\n\n\nor \n\n<div *ngFor=\"let item of items | filterBy: 'nestedObj[key]': search: exact\">\n\n\nDEMO\n\nUpdate#1:\n\nAs requested by OP, there's a version that accepts another parameter (negate):\n\n<div *ngFor=\"let item of items | filterBy: 'nestedObj.key': search: exact: negate\">\n\n\nor \n\n<div *ngFor=\"let item of items | filterBy: 'nestedObj[key]': search: exact: negate\">\n\n\nDEMO\n\n\n\nPS: Note that exact and negate are optionals, if they aren't present, automatically they will be false.",
2017-05-09T12:47:02