fivepointseven
fivepointseven

Reputation: 1051

Filter array by common object property in Angular.js?

I've been struggling with this over a few hours. The situation is, I have an app, that receives data about people in this JSON format:

"people": [
      {
        "name": "Ivan",
        "city": "Moscow",
        "country": "Russia"
      },
      {
        "name": "John",
        "city": "Seattle",
        "country": "United States"
      },
      {
        "name": "Michael",
        "city": "Seattle",
        "country": "United States"
      }
    ]

And I need to filter them into groups based on their city (to be displayed in dropdown <ul>s. I.e. user clicks "Seattle" and <li>s with John and Michael are displayed.

How this can be done?

Upvotes: 1

Views: 313

Answers (4)

darkstalker_010
darkstalker_010

Reputation: 443

You can put the filter in select option which bounds user to select either one city that comes from the server. https://jsfiddle.net/4bhjm5vu/

app.js:

angular.module('myApp', [])
.controller('FooCtrl', function($scope) {
    $scope.people = [
    {
        "name": "Ivan",
        "city": "Moscow",
        "country": "Russia"
    },
    {
        "name": "John",
        "city": "Seattle",
        "country": "United States"
   },
   {
       "name": "Michael",
       "city": "Seattle",
       "country": "United States"
   }
];
})
.filter('unique', function() {
    return function(input, key) {
        var unique = {};
        var uniqueList = [];
        for(var i = 0; i < input.length; i++){
            if(typeof unique[input[i][key]] == "undefined"){
                unique[input[i][key]] = "";
                uniqueList.push(input[i]);
            }
        }
        return uniqueList;
    };
});

html:

<div ng-app="myApp">
    <div ng-controller="FooCtrl">
        <select name="city" ng-model="selectedCity" data-ng-options="person.city as person.city for person in people | unique:'city'"><option data-ng-disabled='true' value="">City</option>
        </select>

        <table class="table">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>City</th>
                    <th>Country</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="person in people | filter: {city: selectedCity}">
                    <td>{{person.name}}</td>
                    <td>{{person.city}}</td>
                    <td>{{person.country}}</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

Upvotes: 1

Phil Quinn
Phil Quinn

Reputation: 146

app.controller('FooCtrl', function($scope) {
   $scope.people = [
      {
        "name": "Ivan",
        "city": "Moscow",
        "country": "Russia"
      },
      {
        "name": "John",
        "city": "Seattle",
        "country": "United States"
      },
      {
        "name": "Michael",
        "city": "Seattle",
        "country": "United States"
      }
    ];
});

And you can filter it like so:

<div ng-repeat="person in people | filter:{ city: 'Seattle' }">

For a dynamic search:

<div ng-app="demo" ng-controller="FooCtrl"><input type="text" ng-model="search.city" >
  <ul>
     <li ng-repeat = "person in people | filter: search"> {{person.name}</li>
  </ul>
</div>

working example

If you used just search as the ng-model it would filter the whole object. But as I used search.city, it filters just that field.

Upvotes: 3

Debasish Mohapatra
Debasish Mohapatra

Reputation: 856

You can try,

<input type="text" ng-model = "search.city" >
<ul>
  <li ng-repeat = "people in peoples | filter: search"> {{people.name}}      </li>
</ul>

See this plunk, http://plnkr.co/edit/SxcorUe1uAszY9FqBJXd?p=preview

Upvotes: 0

Andy Gaskell
Andy Gaskell

Reputation: 31761

Use angular-filter to do the grouping. Your view code will look like this:

<ul ng-repeat="(key, value) in people | groupBy: 'city'">
  City: {{ key }}
  <li ng-repeat="person in value">
    person: {{ person.name }} 
  </li>
</ul> 

Here's a Plunker.

Upvotes: 2

Related Questions