Search code examples
javascriptarraysangularjsangularjs-ng-repeatangularjs-filter

AngularJS - How to order ng-repeat using another array


Say I have an array of keys in a specific order

orderedNames=["mike","bob","sarah];

and I have a JSON that I want to show using ng-repeat but in the order that they appear in the array:

{"people":
    {
    "bob":{
        "hair":"brown",
        "eyes":"blue",
        "height":"tall"
        },
    "sarah":{
        "hair":"blonde",
        "eyes":"blue",
        "height":"short"
        }, 
    "mike":{
        "hair":"red",
        "eyes":"blue",
        "height":"tall"
        }
    }
}

How do I write a filer that would cause ng-repeat to spit out the people in the order in which they are specified in the array?

<li ng-repeat="person in people | orderNames"></li>

Solution

  • You can define a custom filter.

    Plunker: http://plnkr.co/edit/fiuuGoGZK7tM5oefKQlS

    index.html

    <!DOCTYPE html>
    <html ng-app="plunker">
    
    <head>
        <meta charset="utf-8" />
        <title>Filter Example</title>
        <link rel="stylesheet" href="style.css" />
        <script data-require="angular.js@1.2.x" src="http://code.angularjs.org/1.2.15/angular.js" data-semver="1.2.15"></script>
        <script src="app.js"></script>
    </head>
    
    <body ng-controller="MainCtrl">
    <li ng-repeat="person in people|orderNames:orderedNames track by $index">{{person.hair}}</li>
    </body>
    
    </html>
    

    app.js:

    var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope) {
        $scope.people={
            bob:{
                hair:"brown",
                eyes:"blue",
                height:"tall"
            },
            sarah:{
                hair:"blonde",
                eyes:"blue",
                height:"short"
            },
            mike:{
                hair:"red",
                eyes:"blue",
                height:"tall"
            }
        };
        $scope.orderedNames=["mike","bob","sarah"];
    
    });
    
    app.filter("orderNames",function(){
        return function(input,sortBy) {
            var ordered = [];
            for (var key in sortBy) {
                ordered.push(input[sortBy[key]]);
            }
    
            return ordered;
        };
    });