luckybusted
luckybusted

Reputation: 101

Nested JSON in one ng-repeat

I'm somewhat new to angular, and i'm having problems with ng-repeats. I have one ng-repeat that have to show nested objects in each repeat. You know what I mean?

This is the HTML:

<li ng-repeat="rm in rooms">
    <a href="">
        <span id="room">{{rm.room}}</span>
        <span id="rack_num">Rack {{rm.rack}}</span>
        <span id="slot_type">{{rm.type}}</span>
        <span id="slot_id">Slot {{rm.id}}</span>
    </a>
</li>

I have a list of "rooms" and "racks" and "slots":

 [
{
  "room": 1,
  "rackroom": [
    {
      "rack": 8,
      "rackslots": [
        {
          "slot": 1,
          "id": "EZ345T1R",
          "type": "single"
        }
      ]
    },
    {
      "rack": 12,
      "rackslots": [
        {
          "slot": 3,
          "id": "56XZU28",
          "type": "double"
        }
      ]
    }
  ]
},
{
  "room": 2,
  "rackroom": [
    {
      "rack": 12,
      "rackslots": [
        {
          "slot": 1,
          "id": "TZE57DG",
          "type": "single"
        }
      ]
    },
    {
      "rack": 32,
      "rackslots": [
        {
          "slot": 7,
          "id": "778GHRT",
          "type": "double"
        }
      ]
    }
  ]
}
]

My controller looks like this:

$http.get('data/data.json').success(function(data) {

        $scope.rooms = [];
        $scope.slots = [];
        $scope.racks = [];
        angular.forEach(data, function(key, val){
            $scope.rooms.push(key);
            angular.forEach(key.rackroom, function(key, val){
                $scope.racks.push(key);
                angular.forEach(key.rackslots, function(key, val){
                    $scope.slots.push(key);
                });
            });
        });
      });

The output should look something like this:

• Room: 1
• Rack: 12
• Type: single
• Slot: 3

• Room: 1
• Rack: 24
• Type: single
• Slot: 8

It seems like I'm wrong because just the rooms appear but not the nested objects. If I make 3 separate repeats (slot in slots, rack in racks, room in rooms) they all appeear, but I need it all in one repeat ... Thank you for Help!

Upvotes: 1

Views: 1116

Answers (2)

GregL
GregL

Reputation: 38121

I think the following is very close to what you want:

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

app.controller('MainCtrl', function($scope) {
  var data = [{
    "room": 1,
    "rackroom": [{
      "rack": 8,
      "rackslots": [{
        "slot": 1,
        "id": "EZ345T1R",
        "type": "single"
      }]
    }, {
      "rack": 12,
      "rackslots": [{
        "slot": 3,
        "id": "56XZU28",
        "type": "double"
      }]
    }]
  }, {
    "room": 2,
    "rackroom": [{
      "rack": 12,
      "rackslots": [{
        "slot": 1,
        "id": "TZE57DG",
        "type": "single"
      }]
    }, {
      "rack": 32,
      "rackslots": [{
        "slot": 7,
        "id": "778GHRT",
        "type": "double"
      }]
    }]
  }];

  $scope.rooms = [];
  angular.forEach(data, function(room) {

    angular.forEach(room.rackroom, function(rack) {
      angular.forEach(rack.rackslots, function(slot) {
        $scope.rooms.push({
          room: room.room,
          rack: rack.rack,
          type: slot.type,
          slot: slot.slot
        });
      });
    });
  });
});
.room,
.rack_num,
.slot_type,
.slot_id {
  display: list-item;
}
.room_item {
  margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="demo" ng-controller="MainCtrl">
  <ul>
    <li class="room_item" ng-repeat="rm in rooms">
      <a href="">
        <span class="room">Room: {{rm.room}}</span>
        <span class="rack_num">Rack: {{rm.rack}}</span>
        <span class="slot_type">Type: {{rm.type}}</span>
        <span class="slot_id">Slot {{rm.slot}}</span>
      </a>
    </li>
  </ul>
</div>

The markup may not quite be right, but you can tweak it from here.

Also, if you are going to repeat something, you shouldn't use id for those elements. ids are supposed to be unique across the whole page. Use classes instead, like I did.

Upvotes: 0

dting
dting

Reputation: 39287

You basically need to flatten your nested data:

$http.get('data/data.json').success(function(data) {
  $scope.rooms = [];
  for (var i = 0; i < data.length; i++) {
    var room = data[i];
    for (var j = 0; j < room.rackroom.length; j++) {
      var rack = room.rackroom[j];
      for (var k = 0; k < rack.rackslots.length; k++) {
        var slot = rack.rackslots[k];
        $scope.rooms.push({
          room: room.room,
          rack: rack.rack,
          slot: slot.slot,
          type: slot.type
        });
      }
    }
  }
});

<li ng-repeat="rm in rooms">
    <a href="">
        <span id="room">{{rm.room}}</span>
        <span id="rack_num">Rack {{rm.rack}}</span>
        <span id="slot_type">{{rm.type}}</span>
        <span id="slot_id">Slot {{rm.slot}}</span>
    </a>
</li>

Upvotes: 1

Related Questions