161

I'm populating a dropdown through the use of ng-options which is hooked to a controller that in turn is calling a service. Unfortunately the data coming in is a mess and I need to be able to sort it alphabetically.

You figure that something like $.sortBy would do it but unfortunately it didn't do jack. I know I can sort it via javascript with a helper method function asc(a,b) or something like that but I refuse to believe that there is not cleaner way of doing this plus I don't want to bloat the controller with helper methods. It is something so basic in principle so I don't understand why AngularJS doesn't have this.

Is there a way of doing something like $orderBy('asc')?

Example:

<select ng-option="items in item.$orderBy('asc')"></select>

It would be extremely useful to have options in orderBy so you can do whatever you want, whenever you usually try to sort data.

4 Answers 4

343

Angular has an orderBy filter that can be used like this:

<select ng-model="selected" ng-options="f.name for f in friends | orderBy:'name'"></select>

See this fiddle for an example.

It's worth noting that if track by is being used it needs to appear after the orderBy filter, like this:

<select ng-model="selected" ng-options="f.name for f in friends | orderBy:'name' track by f.id"></select>
Sign up to request clarification or add additional context in comments.

13 Comments

Looking at the fiddle (or adding a sort select tag to the Angular ToDo tutorial), getting an option to show as 'selected' - or even getting the first option to show - is an issue. With Angular it's blank?
@DaveEveritt one way to set a default (and to remove the blank item) is to pre-select a bound item for selected. For this example you can do something like $scope.selected = $scope.friends[0]. See this fiddle for a working sample.
what if I want age as value in selected, not the whole JSON element?
@Rishi try this for ng-options: f.age as f.name for f in friends | orderBy:'name' - here is a working fiddle. More on ng-options here.
@Gloopy, This answer got me 90% of the way there. Would you mind adding a case for when track by is used? <select ng-model="selected" ng-options="f.name for f in friends | orderBy:'name' track by f.id"></selected>. Putting track by after order filter wasn't intuitive and this answer is the top search result from google.
|
26

You should be able to use filter: orderBy

orderBy can accept a third option for the reverse flag.

<select ng-option="item.name for item in items | orderBy:'name':true"></select>

Here item is sorted by 'name' property in a reversed order. The 2nd argument can be any order function, so you can sort in any rule.

@see http://docs.angularjs.org/api/ng.filter:orderBy

1 Comment

Or just <select ng-option="item.name for item in items | orderBy:'-name'"></select> Works too :)
2
var module = angular.module("example", []);

module.controller("orderByController", function ($scope) {
    $scope.orderByValue = function (value) {
        return value;
    };

    $scope.items = ["c", "b", "a"];
    $scope.objList = [
        {
            "name": "c"
        }, {
            "name": "b"
        }, {
            "name": "a"
        }];
        $scope.item = "b";
    });

http://jsfiddle.net/Nfv42/65/

4 Comments

A bit of text explaining how this answers the OP's question and/or how you would use it would be very helpful here.
@SeantheBean i have already given fiddle demo so i have not given explaination.
@TechnoCrat An explanation would be preferrable anyway. In fact, it would be particularly interesting to know why this solution would be preferred over the ones posted years earlier. Or, how it differs at all...
@Chipowski ok. going forward i will try to give explanation along with answer.
0

For anyone who wants to sort the variable in third layer:

<select ng-option="friend.pet.name for friend in friends"></select>

you can do it like this

<select ng-option="friend.pet.name for friend in friends | orderBy: 'pet.name'"></select>

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.