1

I have a json structure:

let total_price = "£100";

let product_groups = [
    {
        "name": "group 1",
        "summary": "group 1 summary",
        "products": [
            {
                "name": "product 1",
                "price": "£10",
                ...
            }, 
            ...
        ]
    },
    ...
]

I am trying to flatten this and display it using a table in the following form

<table class="table">
    <thead>
        <tr>
            <th>Group Name</tr>
            <th>Product Name</tr>
            <th>Product Price</tr>
        </tr>
     </thead>
     <tbody>
         <tr ng-repeat="group in product_groups">
             <td>{{group.name}}</td>
             <td>{{product.name}}</td>
             <td>{{product.price}}<td>
         </tr>
         <tr>
             <th colspan="2">Total</th>
             <td>{{total_price}}</td>
         </tr>
     </tbody>
</table>

But this obviously doesnt give me access to each product. Is there a way I can do this using an ng-repeat? Or will I need to flatten my data structure first in the controller?

4 Answers 4

2

You can use nested ng-repeat' and useng-repeat-startandng-repeat-end` try the following.

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

app.controller('MainCtrl', function($scope) {
 $scope.product_groups = [ { "name": "group 1", "summary": "group 1 summary", "products": [ { "name": "product 1", "price": "£10", }, { "name": "product 1", "price": "£10", }, ] }, { "name": "group 2", "summary": "group 2 summary", "products": [ { "name": "product 21", "price": "£20", }, { "name": "product 15", "price": "£80", }, ] } ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="plunker">
  <div ng-controller="MainCtrl">
    <table class="table">
    <thead>
        <tr>
            <th>Group Name</th>
            <th>Product Name</th>
            <th>Product Price</th>
        </tr>
     </thead>
     <tbody>
        <tr ng-repeat-start="group in product_groups"></tr>
         <tr  ng-repeat="product in group.products">
             <td>{{group.name}}</td>
              <td>{{product.name}}</td>
              <td>{{product.price}}</td>
         </tr>
        <tr ng-repeat-end></tr>
     </tbody>
</table>
  </div>
</body>

Sign up to request clarification or add additional context in comments.

5 Comments

Is there a way I could do it without the uppermost ng-repeat being on the tbody? I plan to add an extra tr row at the end for Total Price and this method would end up with duplicates
@Edd Please can you post expected output.
@Edd i have updated the answer, it wont create duplicates now. Please have a look.
ng-repeat-start and ng-repeat-end look very useful thanks
It works but it adds an extra <tr> element either side of each row i'm afraid :( I'm using Bootstrap 4 which adds a lot of extra whitespace for the invisible rows
1

You should flatten your JSON. I suggest changing your structure from:

product_groups = [{
  "name": "group 1",
  "summary": "group 1 summary",
  "products": [{
      "name": "product 1",
      "price": "£10"
    },
    {
      "name": "product 2",
      "price": "£20"
    }
  ]
}]

to:

product_groups = [{
    "name": "group 1",
    "summary": "group 1 summary",
    "product": {
      "name": "product 1",
      "price": "£10"
    }
  },
  {
    "name": "group 1",
    "summary": "group 1 summary",
    "product": {
      "name": "product 2",
      "price": "£20"
    }
  }
]

Then you can simply use this example:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
  $scope.product_groups = [{
      "name": "group 1",
      "summary": "group 1 summary",
      "product": {
        "name": "product 1",
        "price": "£10",
      }
    },
    {
      "name": "group 1",
      "summary": "group 1 summary",
      "product": {
        "name": "product 2",
        "price": "£20",
      }
    }
  ]
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>

<body>

  <div ng-app="myApp" ng-controller="myCtrl">

    <table class="table">
      <thead>
        <tr>
          <th>Group Name</th>
          <th>Product Name</th>
          <th>Product Price</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="group in product_groups">
          <td>{{group.name}}</td>
          <td>{{group.product.name}}</td>
          <td>{{group.product.price}}
            <td>
        </tr>
      </tbody>
    </table>

  </div>

</body>

</html>

Comments

1

Hi try below solution

    $scope.newArray = [];

    let product_groups = [
        {
            "name": "group 1",
            "summary": "group 1 summary",
            "products": [
                {
                    "name": "product 1",
                    "price": "£10",
                }, 
            ]
        },
    ];

for(var i = 0; i< product_groups.length; i++) {
   for(var j =0; j< product_groups[i].products.length; j++) {
    var flattenProduct = {
                           gname:product_groups[i].name, 
                           name:product_groups[i].products[j].name,
                           price : product_groups[i].products[j].price
                        };
        $scope.newArray.push(flattenProduct );
 }

}

And Then call in html like below:

<table class="table">
    <thead>
        <tr>
            <th>Group Name</tr>
            <th>Product Name</tr>
            <th>Product Price</tr>
        </tr>
     </thead>
     <tbody>
         <tr ng-repeat="p in newArray">
             <td>{{p.gname}}</td>
             <td>{{p.name}}</td>
             <td>{{p.price}}<td>
         </tr>
     </tbody>
</table>

Comments

-1

Use a new ng-repeat inside the existing one, like a nested loop.

1 Comment

How do I do that in a table structure?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.