angular ng-repeat in reverse

JavascriptArraysAngularjsReverseAngularjs Ng-Repeat

Javascript Problem Overview


How can i get a reversed array in angular? i'm trying to use orderBy filter, but it needs a predicate(e.g. 'name') to sort:

<tr ng-repeat="friend in friends | orderBy:'name':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>

Is there a way to reverse original array, without sorting. like that:

<tr ng-repeat="friend in friends | orderBy:'':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>

Javascript Solutions


Solution 1 - Javascript

I would suggest using a custom filter such as this:

app.filter('reverse', function() {
  return function(items) {
    return items.slice().reverse();
  };
});

Which can then be used like:

<div ng-repeat="friend in friends | reverse">{{friend.name}}</div>

See it working here: Plunker Demonstration


This filter can be customized to fit your needs as seen fit. I have provided other examples in the demonstration. Some options include checking that the variable is an array before performing the reverse, or making it more lenient to allow the reversal of more things such as strings.

Solution 2 - Javascript

This is what i used:

<alert ng-repeat="alert in alerts.slice().reverse()" type="alert.type" close="alerts.splice(index, 1)">{{$index + 1}}: {{alert.msg}}</alert>

Update:

My answer was OK for old version of Angular. Now, you should be using

ng-repeat="friend in friends | orderBy:'-'"

or

ng-repeat="friend in friends | orderBy:'+':true"

from https://stackoverflow.com/a/26635708/1782470

Solution 3 - Javascript

Sorry for bringing this up after a year, but there is an new, easier solution, which works for Angular v1.3.0-rc.5 and later.

It is mentioned in the docs: "If no property is provided, (e.g. '+') then the array element itself is used to compare where sorting". So, the solution will be:

ng-repeat="friend in friends | orderBy:'-'" or

ng-repeat="friend in friends | orderBy:'+':true"

This solution seems to be better because it does not modify an array and does not require additional computational resources (at least in our code). I've read all existing answers and still prefer this one to them.

Solution 4 - Javascript

Simple solution:- (no need to make any methods)

ng-repeat = "friend in friends | orderBy: reverse:true"

Solution 5 - Javascript

You can reverse by the $index parameter

<tr ng-repeat="friend in friends | orderBy:'$index':true">

Solution 6 - Javascript

You can just call a method on your scope to reverse it for you, like this:

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
    <script>
    angular.module('myApp', []).controller('Ctrl', function($scope) {
        $scope.items = [1, 2, 3, 4];
        $scope.reverse = function(array) {
            var copy = [].concat(array);
            return copy.reverse();
        }
    });
    </script>
</head>
<body ng-controller="Ctrl">
    <ul>
        <li ng-repeat="item in items">{{item}}</li>
    </ul>
    <ul>
        <li ng-repeat="item in reverse(items)">{{item}}</li>
    </ul>
</body>
</html>

Note that the $scope.reverse creates a copy of the array since Array.prototype.reverse modifies the original array.

Solution 7 - Javascript

if you are using 1.3.x, you can use the following

{{ orderBy_expression | orderBy : expression : reverse}}

Example List books by published date in descending order

<div ng-repeat="book in books|orderBy:'publishedDate':true">

source:https://docs.angularjs.org/api/ng/filter/orderBy

Solution 8 - Javascript

If you are using angularjs version 1.4.4 and above,an easy way to sort is using the "$index".

 <ul>
  <li ng-repeat="friend in friends|orderBy:$index:true">{{friend.name}}</li>
</ul>

view demo

Solution 9 - Javascript

When using MVC in .NET with Angular you can always use OrderByDecending() when doing your db query like this:

var reversedList = dbContext.GetAll().OrderByDecending(x => x.Id).ToList();

Then on the Angular side, it will already be reversed in some browsers (IE). When supporting Chrome and FF, you would then need to add orderBy:

<tr ng-repeat="item in items | orderBy:'-Id'">

In this example, you'd be sorting in descending order on the .Id property. If you're using paging, this gets more complicated because only the first page would be sorted. You'd need to handle this via a .js filter file for your controller, or in some other way.

Solution 10 - Javascript

You can also use .reverse(). It's a native array function

<div ng-repeat="friend in friends.reverse()">{{friend.name}}</div>

Solution 11 - Javascript

That's because you are using JSON Object. When you face such problems then change your JSON Object to JSON Array Object.

For Example,

{"India":"IN","America":"US","United Kingdon":"UK"} json object
[{"country":"India","countryId":"IN"},{"country":"America","countryId":"US"},{"country":"United Kingdon","countryId":"UK"}] 

Solution 12 - Javascript

The orderBy filter performs a stable sorting as of Angular 1.4.5. (See the GitHub pull request https://github.com/angular/angular.js/pull/12408.)

So it is sufficient to use a constant predicate and reverse set to true:

<div ng-repeat="friend in friends | orderBy:0:true">{{friend.name}}</div>

Solution 13 - Javascript

I found something like this, but instead of array i use objects.

Here is my solution for objects:

Add custom filter:

app.filter('orderObjectBy', function() {
    return function(items, field, reverse){

        var strRef = function (object, reference) {
            function arr_deref(o, ref, i) {
                return !ref ? o : (o[ref.slice(0, i ? -1 : ref.length)]);
            }
            function dot_deref(o, ref) {
                return !ref ? o : ref.split('[').reduce(arr_deref, o);
            }
            return reference.split('.').reduce(dot_deref, object);
        };

        var filtered = [];
    
        angular.forEach(items, function(item) {
           filtered.push(item);
        });
        filtered.sort(function (a, b) {
           return (strRef(a, field) > strRef(a, field) ? 1 : -1);
        });
        if(reverse) filtered.reverse();
        return filtered;
    };
});

Which can then be used like

<div ng-repeat="(key, value) in items | orderObjectBy:'field.any.deep':true">

If you need old browser support, you will need to define the reduce function (this is only available in ECMA-262 mozilla.org)

// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback /*, initialValue*/) {
'use strict';
  if (this == null) {
    throw new TypeError('Array.prototype.reduce called on null or undefined');
  }
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  var t = Object(this), len = t.length >>> 0, k = 0, value;
  if (arguments.length == 2) {
    value = arguments[1];
  } else {
    while (k < len && !(k in t)) {
      k++; 
    }
    if (k >= len) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    value = t[k++];
  }
  for (; k < len; k++) {
    if (k in t) {
      value = callback(value, t[k], k, t);
    }
  }
  return value;
};
}

Solution 14 - Javascript

I had gotten frustrated with this problem myself and so I modified the filter that was created by @Trevor Senior as I was running into an issue with my console saying that it could not use the reverse method. I also, wanted to keep the integrity of the object because this is what Angular is originally using in a ng-repeat directive. In this case I used the input of stupid (key) because the console will get upset saying there are duplicates and in my case I needed to track by $index.

Filter:

angular.module('main').filter('reverse', function() {
    return function(stupid, items) {
    var itemss = items.files;
    itemss = itemss.reverse();  
    return items.files = itemss; 
  };
});

HTML: <div ng-repeat="items in items track by $index | reverse: items">

Solution 15 - Javascript

Im adding one answer that no one mentioned. I would try to make the server do it if you have one. Clientside filtering can be dangerous if the server returns a lot of records. Because you might be forced to add paging. If you have paging from the server then the client filter on order, would be in the current page. Which would confuse the end user. So if you have a server, then send the orderby with the call and let the server return it.

Solution 16 - Javascript

Useful tip:

You can reverse you're array with vanilla Js: yourarray .reverse()

Caution: reverse is destructive, so it will change youre array, not only the variable.

Solution 17 - Javascript

I would sugest using array native reverse method is always better choice over creating filter or using $index.

<div ng-repeat="friend in friends.reverse()">{{friend.name}}</div>

Plnkr_demo.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDelremmView Question on Stackoverflow
Solution 1 - JavascriptJayView Answer on Stackoverflow
Solution 2 - Javascriptamit bakleView Answer on Stackoverflow
Solution 3 - JavascriptDmitry GoncharView Answer on Stackoverflow
Solution 4 - JavascriptMuhammad HassamView Answer on Stackoverflow
Solution 5 - JavascriptjjhrmsView Answer on Stackoverflow
Solution 6 - JavascriptAnders EkdahlView Answer on Stackoverflow
Solution 7 - JavascriptKumarView Answer on Stackoverflow
Solution 8 - JavascriptvishnuView Answer on Stackoverflow
Solution 9 - JavascriptwhyozView Answer on Stackoverflow
Solution 10 - JavascriptPian0_M4nView Answer on Stackoverflow
Solution 11 - Javascriptuser5891403View Answer on Stackoverflow
Solution 12 - Javascriptuser1012976View Answer on Stackoverflow
Solution 13 - JavascriptTwoisView Answer on Stackoverflow
Solution 14 - JavascriptCoded ContainerView Answer on Stackoverflow
Solution 15 - JavascriptJens AleniusView Answer on Stackoverflow
Solution 16 - JavascriptKe VinView Answer on Stackoverflow
Solution 17 - JavascriptVishnudas Tekale KulkarniView Answer on Stackoverflow