Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have an array of objects and I am using an ng-repeat to iterate over them, which is easy. The array looks something like this:

$scope.steps = [
    {companyName: true},
    {businessType: true},
    {physicalAddress: true}
];

And my ng-repeat attribute looks like:

<div ng-repeat="step in steps"> ... </div>

In each iteration, step is equal to one of the objects, as expected. Is there anyway to access both the key and the value of the step object? So that I could do something like this:

<div ng-repeat="(stepName, isComplete) in steps"> ... </div>

Where stepName == 'companyName' and isComplete == true. I've tried doing this exact thing but stepName always just ends up being the index of the step object (which makes sense). I'm just trying to figure out if there is another way to write the ng-repeat syntax so that I can get the key and the value.

Thanks for any ideas/suggestions. Much appreciated.

PS. My current work around is to just do this in my controller:

$scope.stepNames = [];
angular.forEach($scope.steps, function(isComplete, stepName){
     $scope.stepNames.push({stepName: stepName, isComplete: isComplete});
});

And then to iterate over that, but it would be nice to do it all in the view

share|improve this question
up vote 85 down vote accepted

A repeater inside a repeater

<div ng-repeat="step in steps">
    <div ng-repeat="(key, value) in step">
        {{key}} : {{value}}
    </div>
</div>
share|improve this answer
    
is there a way to do it without having to create two <div>s for every one of my steps? I could make it work but it kinda seems like a pain to have to adjust my css to work around the extra <div>... – tennisgent Oct 23 '13 at 14:48
    
Well you have two iterations, so no (not that I know of, could be wrong). You have to first iterate the array, and then the keys, so an inner loop is the only solution I can think of. – tymeJV Oct 23 '13 at 14:52
1  
Ok, sounds good. I was just hoping there was some cool ng-repeat syntax that I didn't know of like ng-repeat="(key,val) for step in steps" or something similar to ng-options. Thanks for the info though. – tennisgent Oct 23 '13 at 14:59
    
Yeah, Im checking out the docs now, seeing if anything pops out. – tymeJV Oct 23 '13 at 15:00
    
You could probably solve this by writing a directive and having the link function manipulate the data. – KhalilRavanna Oct 23 '13 at 17:01

In fact, your data is not well design. You'd better use something like :

$scope.steps = [
    {stepName: "companyName", isComplete: true},
    {stepName: "businessType", isComplete: true},
    {stepName: "physicalAddress", isComplete: true}
];

Then it is easy to do what you want :

<div ng-repeat="step in steps">
 Step {{step.stepName}} status : {{step.isComplet}}
</div>

Example: http://jsfiddle.net/rX7ba/

share|improve this answer
    
I think KayakDave's design is better, but again it's hard to tell without knowing exactly what the data is for. – NicolasMoise Oct 23 '13 at 16:06
1  
I dont think that an object with a property value designed as a key is a good idea. The proof is that the object has to be inspected by its key/value pairs which is kind of reflection. Anyway if the solution provided suits better...fine, we dont know exactly what is done with the data. – GuillaumeA Oct 23 '13 at 17:25

In case this is an option for you, if you put your data into object form it works the way I think you're hoping for:

$scope.steps = {
 companyName: true,
 businessType: true,
 physicalAddress: true
};

Here's a fiddle of this: http://jsfiddle.net/zMjVp/

share|improve this answer
2  
Yea I agree, this seems like a better data structure. Although, it's hard to tell without knowing exactly what the data is for. – NicolasMoise Oct 23 '13 at 16:05
    
This doesn't preserve the order of key-value pairs in case you want it to be preserved. – mostruash Jul 6 '15 at 15:07
    
And judging from the data structure it would seem order matters. – Aaron Jul 8 '15 at 16:54

I think the problem is with the way you designed your data. To me in terms of semantics, it just doesn't make sense. What exactly is steps for?

Does it store the information of one company?

If that's the case steps should be an object (see KayakDave's answer) and each "step" should be an object property.

Does it store the information of multiple companies?

If that's the case, steps should be an array of objects.

$scope.steps=[{companyName: true, businessType: true},{companyName: false}]

In either case you can easily iterate through the data with one (two for 2nd case) ng-repeats.

share|improve this answer

Here is another way, without the need for nesting the repeaters.

From the Angularjs docs:

It is possible to get ngRepeat to iterate over the properties of an object using the following syntax:

<div ng-repeat="(key, value) in steps"> {{key}} : {{value}} </div>
share|improve this answer

seems like in Angular 1.3.12 you do not need the inner ng-repeat anymore, the outer loop returns the values of the collection is a single map entry

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.