717

In my controller, I have data like: $scope.object = data

Now this data is the dictionary with keys and values from json.

I can access the attribute with object.name in the template. Is there any way that I can iterate over the keys as well and display them in table like

<tr><td> {{key}} </td> <td> data.key </td>

The data is like this

{
    "id": 2,
    "project": "wewe2012",
    "date": "2013-02-26",
    "description": "ewew",
    "eet_no": "ewew",
}

8 Answers 8

1456

How about:

<table>
  <tr ng-repeat="(key, value) in data">
    <td> {{key}} </td> <td> {{ value }} </td>
  </tr>
</table>

This method is listed in the docs: https://docs.angularjs.org/api/ng/directive/ngRepeat

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

20 Comments

It should work: plnkr.co/edit/7AQF6k7hf2aZbWFmhVoX?p=preview. Can you modify that until it stops working?
It works like a charm. The only catch is that it will be alphabetized by the keys so the naming matters if the item order is relevant to the display.
@IsabelHM For many reasons, a lot of us recommend against iterating over objects in an ngRepeat. In fact, I once heard a core team member regret ever implementing the ability to do so! It's usually better to transform the object in the controller to an array; this makes the intent clearer and decreases the risk for strange/unpredictable behavior in certain cases. And you can sort in the usual way. :-)
As IsabelHM said, the output is ordered alphabetically by the name. Is there a way to force it not to do so?
@sethflowers As I mentioned in a previous comment, I don't recommend iterating over keys in objects. It would be better to convert it to an array in your controller. Assuming there isn't idiomatic way to do this based on your business model, ES6 makes it very easy: Object.getOwnPropertyNames(data).map(k => ({key:k, value:data[k]));.
|
142

If you would like to edit the property value with two way binding:

<tr ng-repeat="(key, value) in data">
    <td>{{key}}<input type="text" ng-model="data[key]"></td>
</tr>

4 Comments

Thank you! Out of curiosity, did you find this technique in docs someplace? I searched in vain until finding your answer here.
For some reason the value is updated, and inputs cursor is reset.
@cbk isn't this the same as using ng-model="value"?
@MikeHarrison ng-repeat is essentially iterating over the object and returning key-value pairs. Think of it like for(var value in arrayOfValues) { ... }. If you re-assign the variable value inside your loop, you are not changing what is inside of arrayOfValues, you are just re-pointing value to a new object.
12

I don't think there's a builtin function in angular for doing this, but you can do this by creating a separate scope property containing all the header names, and you can fill this property automatically like this:

var data = {
  foo: 'a',
  bar: 'b'
};

$scope.objectHeaders = [];

for ( property in data ) {
  $scope.objectHeaders.push(property); 
}

// Output: [ 'foo', 'bar' ]

1 Comment

Your answer works fine if one needs to loop through the data inside an angular controller (OP asked for a view loop).
5

we can follow below procedure to avoid display of key-values in alphabetical order.

Javascript

$scope.data = {
   "id": 2,
   "project": "wewe2012",
   "date": "2013-02-26",
   "description": "ewew",
   "eet_no": "ewew",
};
var array = [];
for(var key in $scope.data){
    var test = {};
    test[key]=$scope.data[key];
    array.push(test);
}
$scope.data = array;

HTML

<p ng-repeat="obj in data">
   <font ng-repeat="(key, value) in obj">
      {{key}} : {{value}}
   </font>
</p>

1 Comment

Duplicate in keyword not aloowed
4

A todo list example which loops over object by ng-repeat:

var app = angular.module('toDolistApp', []);
app.controller('toDoListCntrl', function() {
  var self = this;
  self.toDoListItems = {};// []; //dont use square brackets if keys are string rather than numbers.
  self.doListCounter = 0;

  self.addToDoList = function() {		  		   
    var newToDoItem = {};
    newToDoItem.title     = self.toDoEntry;
    newToDoItem.completed = false;		   

    var keyIs = "key_" + self.doListCounter++;  		   

    self.toDoListItems[keyIs] = newToDoItem;		   
    self.toDoEntry = ""; //after adding the item make the input box blank.
  };
});

app.filter('propsCounter', function() {
  return function(input) {
    return Object.keys(input).length;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="toDolistApp">    
  <div ng-controller="toDoListCntrl as toDoListCntrlAs">
    Total Items: {{toDoListCntrlAs.toDoListItems | propsCounter}}<br />
    Enter todo Item:  <input type="text" ng-model="toDoListCntrlAs.toDoEntry"/>
    <span>{{toDoListCntrlAs.toDoEntry}}</span>
    <button ng-click="toDoListCntrlAs.addToDoList()">Add Item</button> <br/>
    <div ng-repeat="(key, prop) in toDoListCntrlAs.toDoListItems"> 
      <span>{{$index+1}} : {{key}}   : Title = {{ prop.title}} : Status = {{ prop.completed}} </span>
    </div>     
  </div>    
</body>

2 Comments

The comment about not using square brackets was really helpful. That change fixed my code. Thanks.
Me too. Can someone explain why using curly brackets fixed my code?
1

Complete example here:-

<!DOCTYPE html >
<html ng-app="dashboard">
<head>
<title>AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link rel="stylesheet" href="./bootstrap.min.css">
<script src="./bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>
<body ng-controller="myController">
    <table border='1'>
        <tr ng-repeat="(key,val) in collValues">
            <td ng-if="!hasChildren(val)">{{key}}</td>  
            <td ng-if="val === 'string'">
                <input type="text" name="{{key}}"></input>
            </td>
            <td ng-if="val === 'number'">
                <input type="number" name="{{key}}"></input>
            </td>
            <td ng-if="hasChildren(val)" td colspan='2'>
                <table border='1' ng-repeat="arrVal in val">
                    <tr ng-repeat="(key,val) in arrVal">
                        <td>{{key}}</td>    
                        <td ng-if="val === 'string'">
                            <input type="text" name="{{key}}"></input>
                        </td>
                        <td ng-if="val === 'number'">
                            <input type="number" name="{{key}}"></input>
                        </td>
                    </tr>
                </table>                
            </td>

        </tr>       
    </table>
</body>

<script type="text/javascript">

    var app = angular.module("dashboard",[]);
    app.controller("myController",function($scope){
        $scope.collValues = {
            'name':'string',
            'id':'string',
            'phone':'number',
            'depart':[
                    {
                        'depart':'string',
                        'name':'string' 
                    }
            ]   
        };

        $scope.hasChildren = function(bigL1) {
            return angular.isArray(bigL1);
} 
    });
</script>
</html>

Comments

1
    Use below code it is working to display your key and value here is key start with 1:
         <tr ng-repeat="(key,value) in alert_list" >
                   <td>{{key +1}}</td>
                   <td>{{value.title}}</td>
                 </tr>
Below is document link for it. 

https://docs.angularjs.org/api/ng/directive/ngRepeat

Comments

0

You can do it in your javascript (controller) or in your html (angular view)...

js:

$scope.arr = [];
for ( p in data ) {
  $scope.arr.push(p); 
}

html:

<tr ng-repeat="(k, v) in data">
    <td>{{k}}<input type="text" ng-model="data[k]"></td>
</tr>

I believe the html way is more angular , but you can also do in your controller and retrieve it in your html...

also not a bad idea to look at the Object keys, they give you the an array of the keys if you need them, more info here:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.