14

Does anybody know how I can SKIP JSON ordering altogether when I use ng-repeat (in a painless way probably)?

For example, my source JSON looks something like this -

{
   "title": "Title",
   "description": "Description",
   "moreInfo": "Moreinformation"
}

Once I use it in ng-repeat, it orders them alphabetically. Something like this -

{
   "description": "Description",
   "moreInfo": "Moreinformation",
   "title": "Title"
}

My ng-repeat looks something like this -

<div ng-repeat="(key,data) in items">
   <span class="one"> {{key}} </span>
   <span class="two"> {{data}} </span>
</div>

I've seen people having a separate array of the keys and using them to identify the JSON objects, ultimately avoiding alphabetical sorting.

Is there an elegant way to do this?

3
  • take a look: jsfiddle.net/DnEXC/5. From here: groups.google.com/forum/#!topic/angular/N87uqMfwcTs Commented Oct 10, 2013 at 6:29
  • @Cherniv That is interesting. Altough it uses a similar approach. It looks pretty neat. Can you post that as one of the answers? (With the code probably). Pretty sure it'll help someone until the Angular folks rectify this issue. Commented Oct 10, 2013 at 15:51
  • yeah , it can be useful , posted ;) Commented Oct 10, 2013 at 16:05

4 Answers 4

38

Nice workaround found at google groups:

    <div ng-repeat="key in notSorted(data)" ng-init="value = data[key]">
         <pre>
               key: {{key}}
               value: {{value}}
         </pre>           
    </div>

And in scope:

    $scope.data = {
        'key4': 'data4',
        'key1': 'data1',
        'key3': 'data3',
        'key2': 'data2',
        'key5': 'data5'
    };

    $scope.notSorted = function(obj){
        if (!obj) {
            return [];
        }
        return Object.keys(obj);
    }

Working: http://jsfiddle.net/DnEXC/

Original: https://groups.google.com/forum/#!topic/angular/N87uqMfwcTs

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

8 Comments

Great, simple solution +1
A live safer ! @Cherniv
this solution breaks Smart-Table pagination feature though, if anyone is using it lorenzofox3.github.io/smart-table-website
You are a god send. +1
please note that ng-init only runs once on initialization (think of it as a one time binding).. so if your values change for data, it will not be reflected. (@SebinSimon i think that is the reason why it's not working for you also)
|
4

This answer using filter works best for me.

https://groups.google.com/d/msg/angular/N87uqMfwcTs/EGoY6O2gtzsJ

http://jsfiddle.net/er52h/1/

angular.module('myFilters', [])
  .filter('keys', function() {
    return function(input) {
      if (!input) {
        return [];
      }
      return Object.keys(input);
    }
  });

You can use like this:

<div ng-repeat="key in data | keys" ng-init="value = data[key]"></div>

1 Comment

This is the cleanest solution.
4

I am using this approach to override the alphabetical ordering:

Controller:

$scope.steps = {
    "basic-settings": "Basic Settings",
    "editor": "Editor",
    "preview-and-publish": "Preview & Publish"
};

// NOTE I realise this is a hacky way, but I need to override JS's alphabetical ordering
$scope.stepsKeys = _.keys($scope.steps);

$scope.activeStep = 0;

PLEASE NOTE that _.keys($scope.steps); is LoDash substituting Object.keys();

HTML:

<ul>
    <li ng-repeat="key in stepsKeys" ng-class="{active : stepsKeys[activeStep] == key}">{{ steps[key] }}</li>
</ul>

Comments

1

At the moment there is no elegant way to do this. Reason being that - ngRepeat creates an associative array, which is called and not the JSON itself. Although the ECMAScript Standard mentions that:

The declaration order of object properties must be preserved, and iteration must happen in the same order.

But somehow, Angular guys overlooked it. This might get rectified in the later releases.

I still think Angular's behaviour makes more sense. As objects often have more initialisation logic around them than arrays, I think it's fair to assume that the order often might not be what the user actually wants/expected, so forcing a specific sorting ensure the proper behaviour - especially when we also have to deal with older browsers.

1 Comment

I agree and disagree. I agree with the fact that expecting order on objects isn't a very good approach. But Angular JS being an awesome framework, one would expect there is an elegant solution (or atleast a solution) to this problem. I'm not sure how having ordinals on objects would affect the framework's performance, but I think it wouldn't hurt to adopt one of the hacks out there to solve this simple issue. So it is ok to not have a solution for this issue. Actually, the comment posted by Cherniv looks pretty decent.

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.