Angular filter a object by its properties

I have an object with a series of object properties that is in the following similar structure (which is the way the data is coming back from a service):

{
  "1": {
    "type": "foo",
    "name": "blah"
  },
  "2": {
    "type": "bar"
  },
  "3": {
    "type": "foo"
  },
  "4": {
    "type": "baz"
  },
  "5": {
    "type": "test"
  }
}

When I do a ng-repeat, I can iterate over all 5 of these object, something like:

<div ng-repeat="item in items">{{item.type}}</div>

However, what I really want to do is iterate only over those items that are NOT the type “foo”, namely 3 iterations instead of 5. I know that filters can somehow be leveraged to do this, but I am not sure how. I tried the following:

<div ng-repeat="item in items| !filter:{type:'foo'}">{{item.type}}</div>

but this doesn’t work. In fact, even doing the following to limit to just 2 objects(those with item.type===”foo”), it doesn’t work and does 5 iterations:

<div ng-repeat="item in items| filter:{type:'foo'}">{{item.type}}</div>

In essence, I want to do something similar to:

<div ng-repeat="item in items" ng-if="item.type !=='foo'>{{item.type}}</div>

However, I know that one doesn’t work.

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

Little late to answer, but this might help :

If you want to filter on a grandchild (or deeper) of the given object, you can continue to build out your object hierarchy. For example, if you want to filter on ‘thing.properties.title’, you can do the following:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter } }">

You can also filter on multiple properties of an object just by adding them to your filter object:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter, id: id_filter } }">

The syntax of ‘not equals’ is just a little off, try the following:

<div ng-repeat="thing in things | filter: { properties: { title: '!' + title_filter } }">

Solution 2

Filter works on arrays but you have an object literal.

So you can either convert your object literal into an array or create your own filter than takes in the object literal.

If you don’t need those index values then converting to an array may be your best bet(
Here’s a fiddle with the array working: http://jsfiddle.net/NqA8d/3/):

$scope.items = [{
    "type": "foo",
        "name": "blah"
}, {
    "type": "bar"
}, {
    "type": "foo"
}, {
    "type": "baz"
}, {
    "type": "test"
}];

In case you’d like to do a filter, here’s one way to do that:

myApp.filter('myFilter', function () {
    return function (items, search) {
        var result = [];
        angular.forEach(items, function (value, key) {
            angular.forEach(value, function (value2, key2) {
                if (value2 === search) {
                    result.push(value2);
                }
            })
        });
        return result;

    }
});

And that fiddle: http://jsfiddle.net/NqA8d/5/

Solution 3

Although I agree that converting your object might be the best option here, you can also use this filter function:

angular.module('app').filter('objectByKeyValFilter', function () {
return function (input, filterKey, filterVal) {
    var filteredInput ={};
     angular.forEach(input, function(value, key){
       if(value[filterKey] && value[filterKey] !== filterVal){
          filteredInput[key]= value;
        }
     });
     return filteredInput;
}});

like this:

<div ng-repeat="(key, value) in data | objectByKeyValFilter:'type':'foo'">{{key}}{{value.type}}</div> 

See also the Plunker.

Solution 4

Try this(in controller):

$scope.notFooFilter = function(item)
{
    return (item.type !== 'foo');
};

And in HTML markup:

<div ng-repeat="item in items| filter:notFooFilter">{{item.type}}</div>

Solution 5

Try this to filter object

var rateSelected = $filter('filter')($scope.GradeList, function (obj) {
                        if(obj.GradeId == $scope.contractor_emp.save_modal_data.GradeId)
                        return obj;
                });

Solution 6

No need of all that. This solution works fine without having to convert or creating your own filter:

 {{myModel.userSelectedHour["Start"]}}

Therefore, object.[“property”] instead of object.property.

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply