Search code examples
javascriptangularjsangular-filters

angular filter - group by object (or multiple fields)


I extended the Angular filter group by example to the following by transforming the team to an object.

     var app = angular.module('myApp',['angular.filter']);

app.controller('MainController', ['$scope', function($scope){
  $scope.players = [
  {
    name: 'Gene', 
    team: {
      'id' : '1',
      'name' : 'alpha'
      
    }
  },
  {
    name: 'George', 
    team: {
      'id' : '2',
      'name' : 'beta'
    }
  },
  {
    name: 'Steve', 
    team: {
      'id' : '3',
      'name' : 'gamma'
    }
  },
  {
    name: 'Paula', 
    team: {
      'id' : '2',
      'name' : 'beta'
    }
  },
  {
    name: 'Scruath', 
    team: {
      'id' : '3',
      'name' : 'gamma'
    }
  }
];
}]);


  
<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
    <script data-require="angular-filter@*" data-semver="0.5.7" src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.7/angular-filter.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="myApp">
    <div ng-controller="MainController">
      <ul>
        <li ng-repeat="(team, players) in players | groupBy: 'team.name'">
          <a href="#I need the team ID">Group name: {{ team }}</a>
          <ul>
            <li ng-repeat="player in players">
              player: {{ player.name }}
            </li>
          </ul>
        </li>
      </ul>
    </div>
  </body>

</html>

But, what if I need the team id in the group by? What can I do?

<a href="#I need the team ID">Group name: {{ team }}</a>

I tried to group by the team object and use team.name and team.id but it didn't work. Also, I didn't know how to create a group by with multiple fields (team.id, team.name)

Here's a working plnkr


Solution

  • I have a simple solution:

    I grouped by team.id

    <li ng-repeat="(teamid, players) in players | groupBy: 'team.id'">
    

    Then I used: players[0].team.name within the group

    <li ng-repeat="(teamid, players) in players | groupBy: 'team.id'">
        <a href="#Here I can use the group teamid">Group name: {{ players[0].team.name }}</a>
          <ul>
            <li ng-repeat="player in players">
              player: {{ player.name }}
            </li>
         </ul>
    </li>
    

    Since players in each group are only the players belonging to this group where all of them have the same team, so players[0], players[1] and so on will have the same team name.

         var app = angular.module('myApp',['angular.filter']);
    
    app.controller('MainController', ['$scope', function($scope){
      $scope.players = [
      {
        name: 'Gene', 
        team: {
          'id' : '1',
          'name' : 'alpha'
          
        }
      },
      {
        name: 'George', 
        team: {
          'id' : '2',
          'name' : 'beta'
        }
      },
      {
        name: 'Steve', 
        team: {
          'id' : '3',
          'name' : 'gamma'
        }
      },
      {
        name: 'Paula', 
        team: {
          'id' : '2',
          'name' : 'beta'
        }
      },
      {
        name: 'Scruath', 
        team: {
          'id' : '3',
          'name' : 'gamma'
        }
      }
    ];
    }]);
    
    
      
    <!DOCTYPE html>
    <html>
    
      <head>
        <script data-require="[email protected]" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
        <script data-require="angular-filter@*" data-semver="0.5.7" src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.7/angular-filter.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js"></script>
      </head>
    
      <body ng-app="myApp">
        <div ng-controller="MainController">
          <ul>
            <li ng-repeat="(teamid, players) in players | groupBy: 'team.id'">
              <a href="#Here I can use the group teamid">Group name: {{ players[0].team.name }}</a>
              <ul>
                <li ng-repeat="player in players">
                  player: {{ player.name }}
                </li>
              </ul>
            </li>
          </ul>
        </div>
      </body>
    
    </html>