jthomasbailey
jthomasbailey

Reputation: 410

How do you sort an AngularFire collection?

  $scope.items = [];
  var ref = new Firebase("https://****.firebaseio.com/");
  var query = ref.limit(5);

  angularFire(query, $scope, "items");

<div ng-repeat="item in items" >
<span>{{item.title}}</span>
</div>

How would you sort these by "title"? I've seen a couple similar questions but the solutions don't seem to work, at least for this situation.

Upvotes: 4

Views: 3341

Answers (1)

hiattp
hiattp

Reputation: 2336

If $scope.items were an array of objects (as implied by $scope.items = []), you would be able to use the angular orderBy filter:

<!-- This example will NOT work with Firebase -->
<div ng-repeat="item in items | orderBy:'title'">
  <span>{{item.title}}</span>
</div>

However, setting items to an array as you did is misleading, because you are actually storing (and retrieving) your "items" as a list of key value pairs, not an array. Sorting objects in javascript is more complicated in general, but one way to achieve what you want is a custom filter:

app.filter('orderObjectBy', function(){
  return function(input, attribute) {
    if (!angular.isObject(input)) return input;

    var array = [];
    for(var objectKey in input) {
      array.push(input[objectKey]);
    }

    function compare(a,b) {
      if (a[attribute] < b[attribute])
        return -1;
      if (a[attribute] > b[attribute])
        return 1;
      return 0;
    }

    array.sort(compare);
    return array;
  }
});

Now you can use your filter to order by any of your item properties:

<div ng-repeat="item in items | orderObjectBy:'title'">
  <span>{{item.title}}</span>
</div>

Here is a fiddle to demonstrate. As @bennlich noted below, your custom filter could stop at the array conversion and then you could use the normal orderBy filter, as suggested here.

And just to be thorough I should note that you could also sort "server-side" with Firebase priorities.

Upvotes: 4

Related Questions