[angularjs] Descending order by date filter in AngularJs

<div class="recent" ng-repeat="reader in
    (filteredItems = (book.reader | orderBy: 'created_at' | limitTo: 1))">
</div>

So the book comes from rest api and it has many readers attached. I want to get the 'recent' reader.

The created_at field has the value which identifies the user as recent. But the above code gives me the oldest reader. So the order needs to be inversed? Is there some way to have the sorting in descending order?

This question is related to angularjs angularjs-filter

The answer is


You can prefix the argument in orderBy with a '-' to have descending order instead of ascending. I would write it like this:

<div class="recent" 
   ng-repeat="reader in book.reader | orderBy: '-created_at' | limitTo: 1">
</div>

This is also stated in the documentation for the filter orderBy.


Descending Sort by date

It will help to filter records with date in descending order.

$scope.logData = [
            { event: 'Payment', created_at: '04/05/17 6:47 PM PST' },
            { event: 'Payment', created_at: '04/06/17 12:47 AM PST' },
            { event: 'Payment', created_at: '04/05/17 1:50 PM PST' }
        ]; 

<div ng-repeat="logs in logData | orderBy: '-created_at'" >
      {{logs.event}}
 </div>

see w3schools samples: https://www.w3schools.com/angular/angular_filters.asp https://www.w3schools.com/angular/tryit.asp?filename=try_ng_filters_orderby_click

then add the "reverse" flag:

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

<p>Click the table headers to change the sorting order:</p>

<div ng-app="myApp" ng-controller="namesCtrl">

<table border="1" width="100%">
<tr>
<th ng-click="orderByMe('name')">Name</th>
<th ng-click="orderByMe('country')">Country</th>
</tr>
<tr ng-repeat="x in names | orderBy:myOrderBy:reverse">
<td>{{x.name}}</td>
<td>{{x.country}}</td>
</tr>
</table>

</div>

<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
    $scope.names = [
        {name:'Jani',country:'Norway'},
        {name:'Carl',country:'Sweden'},
        {name:'Margareth',country:'England'},
        {name:'Hege',country:'Norway'},
        {name:'Joe',country:'Denmark'},
        {name:'Gustav',country:'Sweden'},
        {name:'Birgit',country:'Denmark'},
        {name:'Mary',country:'England'},
        {name:'Kai',country:'Norway'}
        ];

    $scope.reverse=false;
    $scope.orderByMe = function(x) {

        if($scope.myOrderBy == x) {
            $scope.reverse=!$scope.reverse;
        }
        $scope.myOrderBy = x;
    }
});
</script>

</body>
</html>

In my case, the orderBy is determined by a select box. I prefer Ludwig's response because you can set the sort direction in the select options as such:

        $scope.options = [
            { label: 'Title', value: 'title' },
            { label: 'Newest', value: '-publish_date' },
            { label: 'Featured', value: '-featured' }
        ]; 

markup:

<select ng-model="orderProp" ng-options="opt as opt.label for opt in options"></select>
<ul>
    <li ng-repeat="item in items | orderBy:orderProp.value"></li>
</ul>

Perhaps this can be useful for someone:

In my case, I was getting an array of objects, each containing a date set by Mongoose.

I used:

ng-repeat="comment in post.comments | orderBy : sortComment : true"

And defined the function:

$scope.sortComment = function(comment) {
    var date = new Date(comment.created);
    return date;
};

This worked for me.


_x000D_
_x000D_
var myApp = angular.module('myApp', []);_x000D_
_x000D_
myApp.filter("toArray", function () {_x000D_
    return function (obj) {_x000D_
        var result = [];_x000D_
        angular.forEach(obj, function (val, key) {_x000D_
            result.push(val);_x000D_
        });_x000D_
        return result;_x000D_
    };_x000D_
});_x000D_
_x000D_
_x000D_
myApp.controller("mainCtrl", function ($scope) {_x000D_
_x000D_
  $scope.logData = [_x000D_
              { event: 'Payment', created_at: '10/10/2019 6:47 PM PST' },_x000D_
              { event: 'Payment', created_at: '20/10/2019 12:47 AM PST' },_x000D_
              { event: 'Payment', created_at: '30/10/2019 1:50 PM PST' }_x000D_
          ]; _x000D_
        _x000D_
})
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>_x000D_
_x000D_
<div ng-app="myApp" ng-controller="mainCtrl">_x000D_
_x000D_
  <h4>Descending</h4>_x000D_
  <ul>_x000D_
    <li ng-repeat="logs in logData | toArray | orderBy:'created_at':true" >_x000D_
          {{logs.event}} - Date : {{logs.created_at}}_x000D_
    </li>_x000D_
  </ul>_x000D_
  _x000D_
  <br>_x000D_
  _x000D_
  _x000D_
  <h4>Ascending</h4>_x000D_
  <ul>_x000D_
    <li ng-repeat="logs in logData | toArray | orderBy:'created_at':false" >_x000D_
          {{logs.event}} - Date : {{logs.created_at}}_x000D_
    </li>_x000D_
  </ul>_x000D_
  _x000D_
</div>
_x000D_
_x000D_
_x000D_


And a code example:

<div ng-app>
    <div ng-controller="FooController">
        <ul ng-repeat="item in items | orderBy:'num':true">
            <li>{{item.num}} :: {{item.desc}}</li>
        </ul>
    </div>
</div>

And the JavaScript:

function FooController($scope) {
    $scope.items = [
        {desc: 'a', num: 1},
        {desc: 'b', num: 2},
        {desc: 'c', num: 3},
    ];
}

Will give you:

3 :: c
2 :: b
1 :: a

On JSFiddle: http://jsfiddle.net/agjqN/


My advise use moment() is easy to manage dates if they are strings values

//controller
$scope.sortBooks = function (reader) {
            var date = moment(reader.endDate, 'DD-MM-YYYY');
            return date;
        };

//template

ng-repeat="reader in book.reader | orderBy : sortBooks : true"