3

I'm having trouble making proper table with nested ng-repeat.

What I wanted is this https://jsbin.com/razamagabo/1/edit?output

but I'm stuck at here https://plnkr.co/edit/d5voXIpzYL81sSl9BSY2?p=preview

I don't mind my markup is not table but I'm still stuck with div

<div class="row">
            <div class="col-xs-6" ng-repeat="obj in data">
                {{obj.date}}
                <div ng-repeat="user in obj.users">                 
                    <br>
                    {{user.name}}
                    <br>
                    {{user.mark}}
                </div>
            </div>
        </div>
7
  • how do you want to display? Commented Dec 29, 2016 at 16:10
  • @Sajeetharan check the first link Commented Dec 29, 2016 at 16:11
  • your first link data and the plunker data are different, there is no date column Commented Dec 29, 2016 at 16:13
  • 1
    @JessieEmerson - I don't think your going to get there with your current data model. Currently, it is set up for the date to be the row heading and the name to be the column heading. If you don't have control over how your data is structured you'll need to manipulate it in you angular controller Commented Dec 29, 2016 at 16:41
  • 1
    @JessieEmerson Why this particular way of displaying the info? You have a separate row for mark, when a clearer way would be to just display mark in a single row along with the user's information. I concur with @jbrown that it's not possible to achieve the result you want, with the way you have the data structured. This is what you are going to get: plnkr.co/edit/3EHZBCHTSskIjOS3BUI1?p=preview Commented Dec 29, 2016 at 16:44

2 Answers 2

1

In order for you to be able to display your data in the desired way, it will probably be easiest if you restructure your data in the JS before trying to render it.

It will be very complicated to try and match on the user names when they are in separate objects in the data array.

I would suggest processing your scope.data in the controller. (I'm assuming that you don't have much control on how you are receiving the data).

For example after you get your data...

$scope.data = [
    {
        date:'1-1-2016',
        users:[
            {
                'name':'james',
                'mark':18
            },
            {
                'name':'alice',
                'mark':20
            }
        ]
    },
    {
        date:'2-1-2016',
        users:[
            {
                'name':'james',
                'mark':60
            },
            {
                'name':'alice',
                'mark':55
            }
        ]
    }
]

var userData = {};
var possibleDates = [];
for (dataObj of Object.entries($scope.data)) {
    for (userObj of dataObj) {
        if ( !userData[userObj.name] ) {
            userData[userObj.name] = {};
        }
        userData[userObj.name][dataObj.date] = userObj.mark;
        if (dates.indexOf(dataObj.date) < 0) {
            dates.push(dataObj.date);
        }
    }
}

$scope.users = userData;
$scope.dates = possibleDates;

this will give you an object like this on your scope

$scope.users = {
    'james': {
        '1-1-2016': 18,
        '2-1-2016': 60
    },
    'alice': {
        '1-1-2016': 20,
        '2-1-2016': 55
    }
};

$scope.dates = ['1-1-2016', '2-1-2016'];

This to me seems easier to structure for your template. Though this assumes each user has an entry for each date.

<div>
    <div id='header-row'>
        <div id='empty-corner></div>
        <div class='date-header' ng-repeat='date in $scope.dates></div>
    </div>
    <div class='table-row' ng-repeat='{key, value} in $scope.users'>
        <div class='user-name'>{{ key }}</div>
        <div class='user-data' ng-repeat='date in $scope.dates>
            {{ value[date] }}
        </div>   
    </div>
</div>

As long as you apply inline-block styles to the rows/elements this should give you what you are looking for.

Though you can also think of ways to simplify your data even further. You could instead of having each user have an object where the dates are keys, you could just push the values into an array.

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

11 Comments

the user has to be an array. I can't change the data, I have no control over the API.
which is fine, you can restructure the data after you receive it so that you can render it appropriately. You will be unable to do as you hope with the current structure.
There's one way, use css?
even so, as the data is you will not be able to have one row for both instances of james or alice unless you can restructure the data so their values can be combined you will always have to different divs or tds for each occurrence.
you could use css to do a lot of things (it gets very very complicated though and not maintainable), but it's much easier to just restructure the data in your javascript. if i may ask, why would you rather use complicated css when you can easily process the data received from the api in your JS?
|
0

With your current data structure it is not possible to display it like you want. You are trying to loop over date-users objects in data array but then you want to display user from inside users array in separate rows. With ng-repeat you can loop through rows tr but not through columns. First you would need to map your data array to group elements that are supposed to be visible in 1 row into 1 object in array. Currently you have them in 2 separate objects: James mark: 18 and James mark: 60.

Comments

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.