Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs sort object in ngRepeat

I'm using AngularJs and found a problem in ordering properties of a hash object in a template.
My object is like:

function TestCtrl($scope){
    $scope.week = {'MONDAY': ['manuel'], 'TUESDAY': [], 'WEDNESDAY': ['valerio'], 'THURSDAY': ['manuel', 'valerio'], 'FRIDAY': []}
}

Now, when I try to print these values in my template:

<div ng-repeat="(day, names) in week">
    <span>{{day}}</span>
    <ul> <li ng-repeat="name in names">{{name}}</li> </ul>
</div>

The order of the days printed is different: FRIDAY MONDAY THURSDAY TUESDAY WEDNESDAY

I tried to apply the filter orderBy but I think it doesn't work with objects, but just with arrays...

How can I order it?

like image 265
rascio Avatar asked Aug 08 '13 11:08

rascio


2 Answers

As per AngularJS docs (version 1.3.20):

You need to be aware that the JavaScript specification does not define what order it will return the keys for an object. In order to have a guaranteed deterministic order for the keys, Angular versions up to and including 1.3 sort the keys alphabetically.

A workaround is to use an array of keys:

function TestCtrl($scope){
    $scope.week = {
        'MONDAY': ['manuel'], 'TUESDAY': [], 
        'WEDNESDAY': ['valerio'], 'THURSDAY': ['manuel', 'valerio'],    
        'FRIDAY': []}

    $scope.weekDays = ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY"];
}

Use the array in view for iteration:

<div ng-repeat="day in weekDays">
    <span>{{day}}</span>
    <ul> <li ng-repeat="name in week[day]">{{name}}</li> </ul>
</div>

Update from AngularJS version 1.4.6 docs:

Version 1.4 removed the alphabetic sorting. We now rely on the order returned by the browser when running for key in myObj.

like image 198
AlwaysALearner Avatar answered Sep 27 '22 18:09

AlwaysALearner


There is no way to order hash objects like that. Not just in angular but in javascript in general.

I would convert the hash object to an array of objects, something like that:

$scope.week = [{day: 'MONDAY', names: ['manuel']}, {day: 'TUESDAY', names: []} ...];

And then change the view to something like that:

<div ng-repeat="day in week|orderBy:'day'">
    <span>{{day.day}}</span>
    <ul> <li ng-repeat="name in day.names">{{name}}</li> </ul>
</div>
like image 29
Shay Friedman Avatar answered Sep 27 '22 20:09

Shay Friedman