Jordash
Jordash

Reputation: 3103

AngularJS OrderBy Array value of first element of array inside an object

I have an array that looks like this:

$scope.items = {
  books: [
   {position: 1},
   {title: 'Harry Potter'},
   {title: 'Lord of The Rings'}
  ],
  movies: [
   {position: 0},
   {title: 'Mission Impossible'},
   {title: 'Star Wars'}
  ]
};

I want to sort by the first element of the array item, this is what I tried:

<div class="item" ng-repeat="item in items | orderBy:items[0].position">
  {{item}}
</div>

But that gave a syntax error.

Upvotes: 1

Views: 315

Answers (4)

Deepansh Parmani
Deepansh Parmani

Reputation: 123

Items is json object which keys and values. So orderBy:items[0].position doesn't make sense as there is no items[0].

when we do item in items it will iterate through each key of items hence this should work

orderBy : items[item][0].position

Upvotes: 1

Slava Utesinov
Slava Utesinov

Reputation: 13488

You can't apply orderBy to object, so you need to create intermediate $scope.itemsArray and use it instead:

angular.module('app', []).controller('ctrl', function($scope){
  $scope.items = {
    books: [
     {position: 1},
     {title: 'Harry Potter'},
     {title: 'Lord of The Rings'}
    ],
    movies: [
     {position: 0},
     {title: 'Mission Impossible'},
     {title: 'Star Wars'}
    ]
  };
  $scope.itemsArray = [];
  for(var prop in $scope.items){
    var val =  $scope.items[prop];
    $scope.itemsArray.push({key: prop, val, sort: val[0].position})
  }    
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>

<ul ng-app='app' ng-controller='ctrl'>
  <li ng-repeat='item in itemsArray | orderBy : "sort"'>{{item.key}} : {{item.val}}</li>
</ul>

Upvotes: 3

John Velasquez
John Velasquez

Reputation: 3451

You should remap your data, in order to achieve your desired output

model should be like this

[{
  name: string,
  position: number,
  titles: string[]
}]

To achieve that do it like this

$scope.items = {
    books: [
        { position: 1 },
        { title: 'Harry Potter' },
        { title: 'Lord of The Rings' }
    ],
    movies: [
        { position: 0 },
        { title: 'Mission Impossible' },
        { title: 'Star Wars' }
    ]
};
$scope.final = [];
_init();
function _init() {       
    $scope.final = [];
    //Iterate the keys
    for (var x in $scope.items) {
        var data = {
            name: x,//store the key in the name
            position: $scope.items[x][0].position,//position
            titles: []
        }
        //iterate every item 
        for (var y of $scope.items[x]) {
            //push only the title items
            if (y.hasOwnProperty("title")) {
                data.titles.push(y.title);
            }
        }
        $scope.final.push(data);
    }
    console.log($scope.final)
}

In the view should be like this

<div class="item" ng-repeat="item in final | orderBy:'position'">
  {{item.name}}
  <ul>
    <li ng-repeat="title in item.titles">
      {{title}}
    </li>
  </ul>
</div>

Upvotes: 1

Sajeetharan
Sajeetharan

Reputation: 222652

Just use the field name

<div class="item" ng-repeat="item in items | orderBy:'position'">

also you have array inside objects, so you need to iterate over arrays,

div class="item" ng-repeat="item in items.books | orderBy:'position'">

Upvotes: 0

Related Questions