Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter by property being an empty array?

I have this on ng-repeat

<tr ng-repeat="website in websites">
    <td>{{website.url}}</td>
</tr>

Each website object from websites array looks like this:

{
  url: "example.com",
  groups: []
}

Question: How to apply filter to above loop so that it only shows elements where groups property is an empty array?

Things I've tried:

data-ng-repeat="website in websites | filter: {groups: []}"
data-ng-repeat="website in websites | filter: !groups.length"
data-ng-repeat="website in websites | filter: groups.length === 0"

(no errors in console but filters out everything)

data-ng-repeat="website in websites | filter: {groups: ''}"

(does the opposite of what I want, and shows only items where groups is not an empty array)

data-ng-repeat="website in websites | filter: {groups: null}"

(if instead of [] I use null to signify there's no values, this works, but it seems really messy...because I'd need to constantly look out for groups property becoming empty, and setting it to null manually)

like image 931
CodeVirtuoso Avatar asked Apr 13 '15 01:04

CodeVirtuoso


2 Answers

I added a filter function in the controller:

JS:

angular.module('myApp', [])
  .controller('myController', ['$scope',
    function($scope) {
      $scope.friends = [{
        name: 'John', phone: '555-1276', a: [1, 2, 3]
      }, { name: 'Mary',  phone: '800-BIG-MARY',  a: [1, 2, 3]
      }, { name: 'Mike', phone: '555-4321',  a: null
      }, { name: 'Adam', phone: '555-5678', a: []
      }, { name: 'Julie', phone: '555-8765', a: []
      }, { name: 'Juliette', phone: '555-5678', a: []
      }];

      $scope.filterFn = function(item) {
        // must have array, and array must be empty
        return item.a && item.a.length === 0;
      };

    }
  ]);

In your template:

<table>
  <tr><th>Name</th><th>Phone</th><th>array len</th></tr>
  <tr ng-repeat="friend in friends | filter: filterFn">
    <td>{{friend.name}}</td>
    <td>{{friend.phone}}</td>
    <td>{{friend.a.length}}</td>
  </tr>
</table>

Modified Angular Filter doc plnkr

like image 89
Remento Avatar answered Nov 04 '22 03:11

Remento


You could use comparator parameter like this.

<tr ng-repeat="website in websites | filter:{groups: []}:true">
    <td>{{website.url}}</td>
</tr>

Angularjs official document describe the meaning of true.

true: A shorthand for function(actual, expected) { return angular.equals(actual, expected)}. This is essentially strict comparison of expected and actual.

jsfiddle is here.

like image 40
yazaki Avatar answered Nov 04 '22 02:11

yazaki