Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs ng-repeat orderBy not working for nested object properties

I,m trying to ng-repeat nested object properties and order them, but the ordering isn't working for me.

I've seen this: How to orderby in AngularJS using Nested property

but the json structure is different and i couldn't get it to work.

Plunker

My code:

   <div ng-repeat="item in data | orderBy:order.allListPosition">
       <div>{{item.name}} - {{item.order}}</div>
   </div>

The scope:

   $scope.data = {
           "78962": {
                 "id": "78962",
                 "name": "item 2",
                 "type": "blind",
                 "order": {
                       "allListPosition": "008",
                       "catListPosition": "059"
                       },
                 "data": {
                       "status": "stop",
                       "percent": 20
                       },
                 "longPress": {
                       "item": "78966",
                       "active": true
                      }
           },
            "78963": {
                   "id": "78963",
                   "name": "item 3",
                   "type": "coolmaster",
                   "order": {
                         "allListPosition": "053",
                         "catListPosition": "001"
                    },
                    "data": {
                           "status": 1,
                           "temp": 16,
                           "point": 25,
                           "mode": "cool",
                           "fan": 3
                          },
                 "longPress": {
                           "item": "78966",
                           "active": false
                            }
               }
            };

Can anyone please show me what am i doing wrong?

Thank's alot

Avi

like image 574
אVי Avatar asked Jan 05 '15 11:01

אVי


2 Answers

There are two reasons orderBy isn't working here:

  • orderBy only works on arrays, but you are applying it to a plain object.
  • To order by an expression, you need to give orderBy a string value with the expression. You are giving it order.allListPosition, which would equate to $scope.order.allListPosition (which doesn't exist).

To solve the first issue, add an array of your data objects:

$scope.dataArray = Object.keys($scope.data)
  .map(function(key) {
    return $scope.data[key];
  });

To solve the second issue (and incorporate the dataArray from above):

<div ng-repeat="item in dataArray | orderBy:'order.allListPosition'">

http://plnkr.co/edit/BXgYPTElSM3sjvLg30CL?p=preview

like image 78
JLRishe Avatar answered Nov 14 '22 22:11

JLRishe


You can create a custom filter to order by neasted properties.

myApp.filter('customorder', function() {
   return function(items) {  
    items.sort(function(a,b){
        // Make sure we are comparing integers
        var aPos = parseInt(a.order.allListPosition);
        var bPos = parseInt(b.order.allListPosition);

        // Do our custom test
        if (aPos  > bPos ) return 1;
        if (aPos < bPos) return -1;         
        return 0; 
    })
   }
 });

Your html will look like

<div ng-repeat="item in data | customorder">
   <div>{{item.name}} - {{item.order}}</div>
</div>

You should always think that angular is not a restritive language. the filters you normally use are built in filters. But you can have fun with your own filter as soon as you need!

like image 37
nanndoj Avatar answered Nov 14 '22 23:11

nanndoj