6

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

1
  • 1
    Use orderBy:'order.allListPosition' Commented Jan 5, 2015 at 12:06

4 Answers 4

14

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

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

1 Comment

THANK YOU. I owe you a damn nice lunch and drinks.
2

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!

1 Comment

Hi, thanks for your answer. because the $scope.data is an object you can't use sort. can you please show me a plunker example?
2

Your data object is an object of objects, and not an array of objects.

Therefore, orderBy won't work since it is only compatible with arrays.

I have updated your data object to make it work:

$scope.data = [
             {              
              "id": "78961",
              "name": "item 1",
              "type": "blind",
              "order":{allListPosition:"093",catListPosition: "009"}, 
              "data": {
                  "status": "up",
                  "percent": 80
              },
              "longPress": {
                  "item": "78966",
                  "active": true
              }

            },
            {  
              "id": "78962", 
              "name": "item 2",
              "type": "blind",
                "order":{allListPosition:"008",catListPosition: "059"},
              "data": {
                  "status": "stop",
                  "percent": 20
              },
              "longPress": {
                  "item": "78966",
                  "active": true
              }
            },
            {

              "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
              }

            }];

And in HTML:

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

Plunker

1 Comment

Thank's alot but i can't change the data object. that is how i get the data from the api. is there a workaround?
-3

I'm pretty sure this should be:

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

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.