0

Database provides following JSON string.

$scope.items = [
    {"Name":"Michael","Region":"Canada","Subject":"Chemistry","Action":"Email"},
    {"Name":"Michael","Region":"Canada","Subject":"Biology","Action":"Call"},
    {"Name":"Kristen","Region":"USA","Subject":"Chemistry","Action":"Skype"},
    {"Name":"Kristen","Region":"USA","Subject":"Physics","Action":"Email"},
    {"Name":"Kristen","Region":"USA","Subject":"Chemistry","Action":"Call"},
    {"Name":"Kristen","Region":"Europe","Subject":"Chemistry","Action":"Call"},
    {"Name":"Kristen","Region":"Europe","Subject":"Biology","Action":"Call"}
];

Currently displaying data like below: (using ng-repeat)

Name           Region         Subject         Action
Michael        Canada         Chemistry       Email
Michael        Canada         Biology         Call
Kristen        USA            Chemistry       Skype
Kristen        USA            Physics         Email
Kristen        USA            Chemistry       Call
Kristen        Europe         Chemistry       Call
Kristen        Europe         Biology         Call

Expected Result (Tabular Format)

Name          Region        Subject                   Action           
Michael       Canada        Chemistry,Biology         Email,Call
Kristen       USA           Chemistry,Physics         Skype,Email,Call
Kristen       Europe        Chemistry,Biology         Call

Not understood how to use ng-repeat to get expected result (as shown above).

Vojtech Ruzicka
  • 16,384
  • 15
  • 63
  • 66
  • Hi GSerg, Thanks for formatting my question. May I know how you do that? Where you got "Edit" link? – user3172224 Sep 29 '16 at 13:58
  • Possible duplicate of [Angular ng-repeat conditional wrap items in element (group items in ng-repeat)](http://stackoverflow.com/questions/23493063/angular-ng-repeat-conditional-wrap-items-in-element-group-items-in-ng-repeat) – paulwasit Sep 29 '16 at 14:21
  • you can't use ng-repeat alone to do this. You need to map that data yourself first to combine the subjects and actions per person – charlietfl Sep 29 '16 at 14:27

1 Answers1

0

You can't simply using ng-repeat will be able to do such complex grouping but by formatting your data before sending it to ng-repeat we can achieve the above result.

Add below angular.forEach in JS to prepare your data for doing grouping at HTML level

$scope.newList = [];
        var newItemsList = [];
        var nameList = [];
        var regList = [];
        angular.forEach($scope.items, function(val, key) {
            var stud = val;
            var newObj = {};

            newObj.Name = stud.Name;
            newObj.Region = stud.Region;
            newObj.Subject = [];
            newObj.Action = [];
            if (nameList.indexOf(stud.Name) == -1 || regList.indexOf(stud.Region) == -1) {
                newObj.Subject.push(stud.Subject);
                newObj.Action.push(stud.Action);
                newItemsList.push(newObj);
                nameList.push(stud.Name);
                regList.push(stud.Region);
            } else {
                for (var i = 0; i < newItemsList.length; i++) {
                    var item = newItemsList[i];
                    if (item.Name == stud.Name) {
                        if (item.Subject.indexOf(stud.Subject) == -1)
                            item.Subject.push(stud.Subject);
                        if (item.Action.indexOf(stud.Action) == -1)
                            item.Action.push(stud.Action);
                        console.log(newItemsList);
                    }
                }
            }
            $scope.newList = newItemsList;
        });

In HTML add the below template to display the grouped data.

<table>
   <tr >
    <td>Name</td>
    <td>Region</td>
    <td>Subject</td>
    <td>Action</td>
</tr>
<tr ng-repeat="item in newList track by $index">
    <td>{{item.Name}}</td>
    <td>{{item.Region}}</td>
    <td><p ng-repeat="sub in item.Subject track by sub">{{sub}}</p></td>
    <td><p ng-repeat="action in item.Action track by action">{{action}}</p></td>
</tr>
</table>

This is your newly maped data to display

[{"Name":"Michael","Region":"Canada","Subject":["Chemistry","Biology"],"Action":["Email","Call"]},{"Name":"Kristen","Region":"USA","Subject":["Chemistry","Physics","Biology"],"Action":["Skype","Email","Call"]},{"Name":"Kristen","Region":"Europe","Subject":["Chemistry","Biology"],"Action":["Call"]}]
ngCoder
  • 2,095
  • 1
  • 13
  • 22
  • Thank you Angular_10. Your solution helps to resolve my problem. Not understood exactly how "track by" works, but will study more. Thanks one more time to you and Stack Overflow. – user3172224 Sep 30 '16 at 11:17