Question

I want to use ng-repeat in Angular, while I only want to output some elements of the array. An Example:

ng-repeat="item in items | filter:($index%3 == 0)"

However, this does not work. Please tell me how to do this; only output exact index of elements.

Was it helpful?

Solution

In your code, filter apply on 'items' array, not on each array item, that's why it does not work as you expect.

Instead, you can use ng-show (or ng-if):

<ul>
    <li ng-repeat="item in items" ng-show="$index % 3 == 0">{{item}}</li>
</ul>

See: http://jsfiddle.net/H7d26

EDIT: Use ng-if directive if you do not want to add invisible dom elements:

<ul>
    <li ng-repeat="item in items" ng-if="$index % 3 == 0">{{item}}</li>
</ul>

OTHER TIPS

Create a custom filter, for example:

filter('modulo', function(){
  return function (arr, div, val) {
      return arr.filter(function(item, index){
          return index % div === (val || 0);
      })
  };
});

Then change the ng-repeat to:

<ul ng-repeat="item in items | modulo:3">

Or filter by (index % 3 === 1) like:

<ul ng-repeat="item in items | modulo:3:1"> 

http://jsfiddle.net/Tc34P/2/

What you need to do is find the index of "item" in $scope.items. See below

ng-repeat"item in items | filter:(items.indexOf(item)%3 == 0)

So a real world example (for others who come across this solution) would be.

<div ng-repeat="item in filtered = (items | filter:customfilter | orderBy:customsort)">
    <div> This is number {{items.indexOf(item)}} in the items list on the scope.</div>
</div>

The above example will get the correct position regardless of the sorting or filtering

All the precedent answers will work, but if you want to use a filter, you can also define it yourself, like in this fiddle : http://jsfiddle.net/DotDotDot/58y7u/

.filter('myFilter', function(){
    return function(data, parameter){
        var filtered=[];
        for(var i=0;i<data.length;i++){
                if(i%parameter==0)
                    filtered.push(data[i]);
        }
        return filtered;
    }
});

and then call it like this :

ng-repeat='item in items | myFilter:3'

(I added extra complexity with a parameter, if you want to change it quickly to even numbers for example)

Have fun

++

I suggest filtering with a function:

ng-repeat"item in filterItems(items)"

And on the Controller:

$scope.filterItems= function(items) {
    var result = {};
    angular.forEach(items, function(item) {
       // if item is something.. add to result
    });
    return result;
}

An alternate approach to solving this creates a new "list" (I don't know the proper term in this context) in the ng-repeat. This new list can then be referred to within the scope

<ul class="example-animate-container">
  <li class="animate-repeat" ng-repeat="friend in filteredFriends = ((friends | filter:q:strict) | orderBy:'age')" ng-if="$index % 2 == 0">
    [{{$index + 1}}] {{filteredFriends[$index].name}} who is {{filteredFriends[$index].age}} years old.
    <span ng-if="$index+1 < filteredFriends.length">[{{$index + 2}}] {{filteredFriends[$index+1].name}} who is {{filteredFriends[$index+1].age}} years old.</span>
  </li>
</ul>

The ng-if on the span wrapping the second half prevents the base text from being shown when the previous element is the last element of the list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top