Markus Johansson
Markus Johansson

Reputation: 3773

Angularjs filter only first level properties

I have javascript object which look like this:

{ name: 'Barney', color: 'blue', parent: {name: 'Henry'} }

When I use $filter('filter')('Henry') on an array which includes the object above, I don't want it to be included as a result. I only want to filter out things matching on the first level, in this case the 'name' and 'color' properties.

Is it possible?

Upvotes: 1

Views: 485

Answers (2)

JDWardle
JDWardle

Reputation: 923

You'd want to create a custom filter since the default filter provided by Angular appears to do a deep comparison.

Here's an example I came up with real quick, you may want to change the filter to suit your needs:

// Looks like a nice little tree :)
app.filter('shallowFilter', function () {
    return function (items, value) {
        if (!angular.isDefined(value) || value === '') {
            return items;
        }

        return items.filter(function (item) {
            for (var prop in item) {
                if (item.hasOwnProperty(prop)) {
                    var propVal = item[prop],
                        propLower,
                        valLower;

                    // Skip values that are not a string..
                    if (typeof propVal !== 'string') {
                        continue;
                    }

                    propLower = propVal.toLowerCase();
                    valLower = value.toLowerCase();

                    if (propLower.indexOf(valLower) !== -1) {
                        return true;
                    }
                }
            }
        });
    };
});

Here's a plunker demonstrating how it works.

Edit:

This will only loop over the "low level" properties of an object (shallow search), which is what I assume you want.

Upvotes: 2

William Lepinski
William Lepinski

Reputation: 917

Use the object notation:

From documentation: Object: A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1". A special property name $ can be used (as in {$:"text"}) to accept a match against any property of the object. That's equivalent to the simple substring match with a string as described above. The predicate can be negated by prefixing the string with !. For Example {name: "!M"} predicate will return an array of items which have property name not containing "M".

$filter('filter')({ name: 'Henry' });

Upvotes: 0

Related Questions