3

I have been stuck on displaying data with ng-repeat. the only thing I have been able to do is display the one of the two objects. Every Customer can have multiple Users. I am trying to display the Users in a table with there CustomerId. Working plunkr

app.controller('MainCtrl', function ($scope) {
var json = [
    {
        "CustomerId": "12xsd-344-fv23", "CompanyName": "ConocoPhillips",
        "Address": "1234 Main St", "City": "Redmond", "State": "WA", "Zip": "10999",
        "Email": "debra@example.com",
        "Users": [
             {
                 "FirstName": "Rudy", "LastName": "Sanchez", "CustomerId": "12xsd-344-fv23", "Customer": null,
                 "Email": "admin@energy.com", "EmailConfirmed": true, "PasswordHash": "AGtuCXr",
                 "SecurityStamp": "b0fca140", "PhoneNumber": null, "PhoneNumberConfirmed": false, "TwoFactorEnabled": false,
                 "LockoutEndDateUtc": null, "LockoutEnabled": false, "AccessFailedCount": 0, "Roles": [], "Claims": [], "Logins": [],
                 "Id": "49b5", "UserName": "admin"
             },
             {
                 "FirstName": "Troy", "LastName": "Benbow", "CustomerId": "12xsd-344-fv23", "Customer": null,
                 "Email": "tbenbow@yahoo.com", "EmailConfirmed": true, "PasswordHash": "AM8wL+iHaSG",
                 "SecurityStamp": "14f1483a-2e6f-41da-8307-a6c5945984a9", "PhoneNumber": null, "PhoneNumberConfirmed": false, "TwoFactorEnabled": false,
                 "LockoutEndDateUtc": null, "LockoutEnabled": true, "AccessFailedCount": 0, "Roles": [], "Claims": [], "Logins": [],
                 "Id": "9985b820-a45", "UserName": "tbenbow"
             }
        ]
    },
];
$scope.customers = json;

});

texas697
  • 5,609
  • 16
  • 65
  • 131

2 Answers2

2

Since, CustomerId is also a property of User, you could make a list of Users in the controller and then loop them in the table:

  $scope.users = [];
  for(var i = 0; i < $scope.customers.length; i++) {
    for(var j = 0; j < $scope.customers[i].Users.length; j++) {

        //now you have access to customer properties with $scope.customers[i]
        var user = $scope.customers[i].Users[j];

        //example of adding CompanyName property
        user.CompanyName = $scope.customers[i].CompanyName;  

        //add user to $scope.users 
        $scope.users.push(user);
    }

  }

And then just ng-repeat the users:

<tr ng-repeat="user in users">
  <td>{{user.FirstName}} {{user.LastName}}</td>
  <td>{{user.UserName}}</td>
  <td>{{user.Email}}</td>
  <td>{{user.CustomerId}}</td>
  <td>{{user.CustomerName}}</td>
</tr>

Here is an updated plunker.

In fact, even if you need a property on the parent Customer part of json, you can add the property to the users array being repeated.

Preparing the data for view will often simplify template tricks (like having to build the table with extra ng-repeated elements. IMO, this is preferable.

Davin Tryon
  • 66,517
  • 15
  • 143
  • 132
  • I forgot to mention I need to be able to add some Customer properties to the same table. That's why I was trying to go through the customers to the users data. Sorry. – texas697 Feb 01 '15 at 23:17
  • Like I mentioned, you can easily do this in the same loop (as you prepare the `users` array). You can add a further loop for each user and then add the properties from the parent. – Davin Tryon Feb 01 '15 at 23:19
  • Sorry. I should take more time to read everything. So where exactly would I add the parents property? I'm kind of lost on adding a additional loop. Thanks for your help – texas697 Feb 01 '15 at 23:55
  • I've made an update showing how to add the parent properties during the loop. I've also updated the plunker to include CompanyName (from customer). – Davin Tryon Feb 02 '15 at 09:10
1

There are two possible solutions for this problem, the first one ( rearranging your data in your controller) has already been mentioned in the other answer.

Another way would be a nested loop which I implemented like this:

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <script>document.write('<base href="' + document.location + '" />');</script>
  <link rel="stylesheet" href="style.css">
  <script src="http://code.angularjs.org/1.1.4/angular.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
 <table class="table table-bordered">
   <thead>
    <tr>
     <th>Name</th>
     <th>UserName</th>
     <th>Email</th>
     <th>CustomerId</th>
    </tr>
   </thead>
    <tbody ng-repeat="customer in customers">
      <tr ng-repeat="user in customer.Users">
        <td>{{user.FirstName}} {{user.LastName}} {{customer.CustomerId}}</td>
        <td>{{user.UserName}}</td>
        <td>{{user.Email}}</td>
        <td>{{user.CustomerId}}</td>
      </tr>
    </tbody>
 </table>
</body>
</html>

This solution is fast and easy to implement and gives you access to both the user and customer. I would still suggest to rebuild your data in your controller most of the time as it keeps your views clean and keeps any real logic in your controller (Check here for an example of that).

But this example is so simple that you can easily handle it in a nested ng-repeat.

Community
  • 1
  • 1
Bricktop
  • 1,549
  • 14
  • 23
  • This will repeat a `tbody` for every customer, which is not valid HTML. But, it might work in some browsers. – Davin Tryon Feb 02 '15 at 09:05
  • @DavinTryon I am not sure about the validity of the html but as far as I know it should work in any browser ( see also [here](http://stackoverflow.com/a/3076790/4360457) ; the fifth comment in particular) , please let me know if there is a case where this doesn't work. – Bricktop Feb 02 '15 at 09:19
  • I went with data in the controller as you suggested. this did work fine though. thank you very muc! – texas697 Feb 02 '15 at 14:41