3

I want to show an array from another array in a list. I want to use ng-repeat to show the array in a list. I´ve tried all sorts of combinatins, but i can't make it work. I have the following code:

var workouts = this;  
    workouts.workoutslist = [  
        {'workoutId': 1,   
         'workoutName': "Maandag",  
         'exercises':  
                    [   
                        {exerciseId: 1,  
                        exerciseName: "exercise1"},  
                        {exerciseId: 2,  
                        exerciseName: "exercise2"}  
                    ]  
        },  
        {
            'workoutId': 2,   
            'workoutName': "Dinsdag",  
            'exercises':  
                    [ 
                        {exerciseId: 3,  
                        exerciseName: "exercise3"},  
                        {exerciseId: 4,  
                        exerciseName: "exercise4"}  
                    ]
        }
    ];

This works:

<li class="item" ng-repeat="workoutTest in workout.workoutslist[0].exercises">{{ workoutTest.exerciseName }}
            </li>

But this doesn't:

    <li class="item" ng-repeat="workoutTest in workout.workoutslist.exercises  |filter:{workoutId: workoutId}">
{{ workoutTest.exerciseName }}
                </li> 

Am i not saying exactly the same in my second code?
EDIT: Plunker: http://plnkr.co/edit/1VQBkuTWAVatexPMsxOd?p=preview

6
  • could you provide a plunker with simplified controller? Commented Mar 13, 2015 at 9:37
  • Are you using nested ng-repeat or not? Commented Mar 13, 2015 at 9:38
  • Use nested ng-repeat. for you knoledge follow stackoverflow.com/questions/19839743/nested-ng-repeat Commented Mar 13, 2015 at 9:40
  • Do i also have to use nested ng-repeat if i don't want to show my workout? I only want to show the exercises. I have the workouts on another page. Commented Mar 13, 2015 at 9:49
  • no, you aren't saying the same thing. workoutslist is an array of objects, each with an exercises array. you have 2 loops, one through the array of objects, and one through the array inside the objects. Commented Mar 13, 2015 at 9:54

4 Answers 4

3

Problem explanation:

This works because it targets exercises of single workout:

workoutTest in workout.workoutslist[0].exercises

This not works:

workoutTest in workout.workoutslist.exercises | filter:{workoutId: workoutId}

because filter applied to nonexistent property "exercises" of workoutlist array.

Solution 1:

If you want to display exercises of single workout selected by id - try to define your workouts as object like this:

workouts.workoutslist = { 
    "1": {
        'workoutName': "Maandag",  
        'exercises': [   
            {exerciseId: 1, exerciseName: "exercise1"},  
            {exerciseId: 2, exerciseName: "exercise2"}  
        ]  
    },  
    "2": {
        'workoutName': "Dinsdag",  
        'exercises': [ 
            {exerciseId: 3, exerciseName: "exercise3"},  
            {exerciseId: 4, exerciseName: "exercise4"}  
        ]
    }
};

and access it like this:

exercise in workout.workoutslist[workoutId].exercises

Solution 2:

If you want to display list of workouts that contain lists of exercises than implement two-level list like this:

<ul>
    <li ng-repeat="w in workout.workoutslist">
        <span>{{w.workoutName}}<span>
        <ul>
            <li ng-repeat="e in w.exercises">{{e.exerciseName}}</li>
        </ul>
    </li>
</ul>
Sign up to request clarification or add additional context in comments.

2 Comments

I would like to use solution 1, but how do i make the workoutId in exercise in workout.workoutslist[workoutId].exercises dynamic?
Add variable workoutId in your controller and use it like this (I assume that you use controller as "workout"): exercise in workout.workoutslist[workout.workoutId].exercises.
1

You can ng-repeat nested arrays like this:

<li ng-repeat="workout in workoutslist">
  <ul>
    <li ng-repeat="exercise in workout.exercises"></li>
  </ul>
</li>

Note it's a lot simpler that what you have - i'd also define the object differently. This is easier:

$scope.workoutslist = [];

Instead of:

workouts.workoutslist = [];

JSFiddle

2 Comments

This works, but is it ok to use: <li ng-repeat="workout in workoutslist"> if i don't want show anything from the workout except the exercises?
@Edgar It would work, but it's not a good practice - you'd be iterating over items that you don't want. If you only want to use the nested arrays, It would be far better and easier to have that as an object - essentially, separating the objects that you have currently and use one 'regular' ng-repeat. Anyway, this answers your original question about using nested arrays in ng-repeat.
0

It doesn't look like your second extract could work. If I take the first example, we have the following types for the different elements used in your ng-repeat directive:

workout --> object
workout.workoutslist --> array
workout.workoutslist[0] --> object
workout.workoutslist[0].exercises --> array

Do the same exercise with the second code extract and you will see how it doesn't work.

workout.workoutlist --> array
workout.workoutlist.exercises --> ???

Actually, I am not even sure what you are trying to do with the filter after that (but I haven't had the opportunity to use AngularJS that much so far, so it may just be that I haven't come across that kind of use of filter yet).

If you only want to list the exercises, not caring about the workouts containing them, the best thing to do is probably to define a function in your controller that takes care of building the array of exercice objects and use that with ng-repeat. You could also, of course, use nested ng-repeats but each would have to be bound to a different HTML element, something you probably cannot do in your context.

Comments

0

use it like a simple nested loop.. a cleaner way would be like...

<li ng-repeat="workout in workoutslist"> <ul> <li ng-repeat="exercise in workout.exercises"></li> </ul> </li>

1 Comment

Is this best practice to use te li element like that? Because i don't want to show elements of the workout, only the exercises.

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.