LBA LBA - 27 days ago 5
AngularJS Question

Two ng-repeat with independent objects sorted by keys

To be very honest I don't even know how to exactly design this.

From two different sources I'll get two pretty complex objects (simplified):

var header = {
fieldName1: {otherstuff: x},
fieldName2: {otherstuff: y},
fieldName3: {otherstuff: z}
}

var data = [
{
fieldName3: {someData: 1},
fieldName2: {someData: 2},
fieldName4: {someData: 3}
},
{
fieldName2: {someData: 11},
fieldName3: {someData: 22},
fieldName1: {someData: 33}
}
];


I want to build up a table with a table header row which displays the keys of the first object and table rows build with someData values from the second object.

But of course, data columns require same order as the table header rows.

<table>
<tr>
<th ng-repeat="(fieldKey, fieldMeta) in header">{{fieldKey}}: {{fieldMeta.label}}</th>
</tr>
<tr ng-repeat="row in data">
<td ng-repeat="value in row">{{value}}</td>
</tr>
</table>


So how should I approach this?
Should I try to sort the header and data objects first (as objects or should I transform into arrays first) or is there an option to achieve the same by an orderBy in the second ng-repeat?

I am pretty sure when I spend a day or two I come up with a solution which consists of 100 lines of code in several utility classes trying to solve issue by issue.

I don't need a readymade code, but some guidance from experienced JS guys would be highly appreciated.

Answer

You could try repeating over your header in the second internal ng-repeat, and use the keys to access the appropriate row data. That way the order of the data in your header acts as the defined order. Not sure on performance though of this method. For example:

<table>
  <tr>
    <th ng-repeat="(fieldKey, fieldMeta) in header">{{fieldKey}}: {{fieldMeta.label}}</th>
  </tr>
  <tr ng-repeat="row in data">
    <td ng-repeat="(key, meta) in header">{{row[key]}}</td>
  </tr>
</table>

Sample fiddle here. Just note, that it isn't the best idea to order things by object keys, as the order is not guaranteed, so I would suggest converting to arrays of individual objects.