Home:ALL Converter>How to create an Angular2 filter pipe that acts such as Angular1 filter?

How to create an Angular2 filter pipe that acts such as Angular1 filter?

Ask Time:2017-05-09T18:43:23         Author:smartmouse

Json Formatter

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.

Author:smartmouse,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/43867657/how-to-create-an-angular2-filter-pipe-that-acts-such-as-angular1-filter
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
yy