0

I've got an application where I retreive the information of some objects (into an array). That array would have the following structure:

$scope.items = [    
    {
        id: 23289323,
        event: {
            id: 972823,
            name: 'Event A name',
            datetime: '2017-02-01 13:45',
        },
        player: {
            id: 58392,
            name: 'Player A name'
        },
        team: {
            id: 38839,
            name: 'Team A'
        },
        datetime: '2017-02-03 22:23'
    },
    {
        id: 482273784,
        event: {
            id: 972823,
            name: 'Event A name',
            datetime: '2017-02-01 13:45',
        },
        player: {
            id: 2989273,
            name: 'Player B name'
        },
        team: {
            id: 2323434,
            name: 'Team B'
        },
        datetime: '2017-02-03 22:23'
    },
    {
        id: 283273939,
        event: {
            id: 23092803,
            name: 'Event B name',
            datetime: '2017-02-01 13:45',
        },
        player: {
            id: 58392,
            name: 'Player A name'
        },
        team: {
            id: 38839,
            name: 'Team A'
        },
        datetime: '2017-02-03 22:23'
    }
    ...
]

What I'd like

I'd like to be able to have two lists.

On the left, a list of some customizable groupingBy AngularJS filter. So, I can specify "group it by player" and it shows, on this left list, a list of the players with some information (for example, showing the player's name).

On the right, when I select a specific player, show the items that have this player associated.

What I've tried

<li data-ng-repeat="(key, value) in Ctrl.items | groupBy: 'event.id'">
{{key}}<br/>{{value}}
</li>

What I get

23289323
{id: 23289323,event: {id: 972823,name: 'Event name',datetime: '2017-02-01 13:45',}, player: {id: 58392, name: 'Player name'}, team: { id: 38839,name: 'Team A'}, datetime: '2017-02-03 22:23'}

So, I'm getting the whole item object, but I've not found any way of getting the item that I'm groupBying. Because, right now, if there are 3 items with that event.id I get three <li></li> in stead of only one (the one of the event object).

What I ask

Is there any way of using AngularJS groupBy filter and getting in return the (whole) object that is specifying the grouping?

Remember that the groupBy key can be changed by the user.

If you need any further information, please let me know.

Thank you!

Unapedra
  • 2,043
  • 4
  • 25
  • 42
  • Can you also post the code for the `groupBy` filter? – couzzi May 09 '17 at 17:55
  • It's not a filter made by me, but included in angular.filter module. You can see it here: http://stackoverflow.com/questions/14800862/how-can-i-group-data-with-an-angular-filter (and I think there is the code here: http://jsfiddle.net/drubarth/R8YZh/). Thank you! – Unapedra May 09 '17 at 18:01
  • I understand what you're saying, but `groupBy` relies heavily on your data structure, which right now is just an object with no similar values to group or differentiate from. Can you expand on what `Ctrl.items` is? Should have more data to work with... (more events, etc) – couzzi May 09 '17 at 18:09
  • Done! Question updated. As you can see, all the objects have the same fields, the only that changes is the properties of the subobjects like `event`, `player`, and so on. Thank you! – Unapedra May 10 '17 at 08:33

1 Answers1

0

I think I've made it through a custom filter. I'm not sure if it's the best way, so if anyone has another solution, please post it!

This is the code of the filter:

(function(){
    angular.module("AppModule").filter('groupByGrouped', function() {
        return function(list, groupedElement) {
            var result = [];
            var used_elements = [];
            var ref_item;
            var ref_check;

            // Loop through every list item
            angular.forEach(list, function(item){
                // We take the object we want to group by inside the item 
                ref_item = item[groupedElement];

                // If it exists
                if(ref_item !== undefined){
                    if(ref_item.id !== undefined){
                        // If it has an ID, we take the ID to make it faster. 
                        ref_check = ref_item.id;
                    }else{
                        // Otherwise, we identify the specific object by JSON string (slower method)
                        ref_check = JSON.stringify(ref_item);
                    } 

                    // If it does not exist yet
                    if(used_elements.indexOf(ref_check) == -1){
                        // We add it to the results
                        result.push(ref_item);
                        // And we add it to the already used elements so we don't add it twice
                        used_elements.push(ref_check);
                    }
                }else{
                    // Otherwise we log it into our console
                    console.warn("The key '"+groupedElement+"' inside the specified item in this list, does not exist.");
                }
            });

            return result;
        };
    });
})();

This will return the whole object. So our HTML would be something like:

<ul>
    <li data-ng-repeat="(key, obj) in Ctrl.items | groupByGrouped: 'event'">
        <span class="object_id">{{obj.id}}</span>
    </li>
</ul>

Or even with a directive (not tested, but should work aswell):

<ul>
    <li data-ng-repeat="(key, obj) in Ctrl.items | groupByGrouped: 'event'">
        <obj_directive ourobject="obj"></obj_directive>
    </li>
</ul>
Unapedra
  • 2,043
  • 4
  • 25
  • 42