AngularJS Built-in directives ngRepeat


Example

ng-repeat is a built in directive in Angular which lets you iterate an array or an object and gives you the ability to repeat an element once for each item in the collection.

ng-repeat an array

<ul>
    <li ng-repeat="item in itemCollection">
       {{item.Name}}
    </li>
</ul>

Where:
item = individual item in the collection
itemCollection = The array you are iterating


ng-repeat an object

<ul>
    <li ng-repeat="(key, value) in myObject">
       {{key}} : {{value}}
    </li>
</ul>

Where:
key = the property name
value = the value of the property
myObject = the object you are iterating


filter your ng-repeat by user input

<input type="text" ng-model="searchText">
<ul>
    <li ng-repeat="string in stringArray | filter:searchText">
       {{string}}
    </li>
</ul>

Where:
searchText = the text that the user wants to filter the list by
stringArray = an array of strings, e.g. ['string', 'array']

You can also display or reference the filtered items elsewhere by assigning the filter output an alias with as aliasName, like so:

<input type="text" ng-model="searchText">
<ul>
    <li ng-repeat="string in stringArray | filter:searchText as filteredStrings">
       {{string}}
    </li>
</ul>
<p>There are {{filteredStrings.length}} matching results</p>

ng-repeat-start and ng-repeat-end

To repeat multiple DOM elements by defining a start and an end point you can use the ng-repeat-start and ng-repeat-end directives.

<ul>
    <li ng-repeat-start="item in [{a: 1, b: 2}, {a: 3, b:4}]">
        {{item.a}}
    </li>
    <li ng-repeat-end>
        {{item.b}}
    </li>
</ul>

Output:

  • 1
  • 2
  • 3
  • 4

It is important to always close ng-repeat-start with ng-repeat-end.

Variables

ng-repeat also exposes these variables inside the expression

VariableTypeDetails
$indexNumberEquals to the index of the current iteration ($index===0 will evaluate to true at the first iterated element; see $first)
$firstBooleanEvaluates to true at the first iterated element
$lastBooleanEvaluates to true at the last iterated element
$middleBooleanEvaluates to true if the element is between the $first and $last
$evenBooleanEvaluates to true at an even numbered iteration (equivalent to $index%2===0)
$oddBooleanEvaluates to true at an odd numbered iteration (equivalent to $index%2===1)

Performance considerations

Rendering ngRepeat can become slow, especially when using large collections.

If the objects in the collection have an identifier property, you should always track by the identifier instead of the whole object, which is the default functionality. If no identifier is present, you can always use the built-in $index.

<div ng-repeat="item in itemCollection track by item.id">
<div ng-repeat="item in itemCollection track by $index">

Scope of ngRepeat

ngRepeat will always create an isolated child scope so care must be taken if the parent scope needs to be accessed inside the repeat.

Here is a simple example showing how you can set a value in your parent scope from a click event inside of ngRepeat.

scope val:  {{val}}<br/>
ctrlAs val: {{ctrl.val}}
<ul>
    <li ng-repeat="item in itemCollection">
        <a href="#" ng-click="$parent.val=item.value; ctrl.val=item.value;">
            {{item.label}} {{item.value}}
        </a>
    </li>
</ul>

$scope.val = 0;
this.val = 0;

$scope.itemCollection = [{
    id: 0,
    value: 4.99,
    label: 'Football'
},
{
    id: 1,
    value: 6.99,
    label: 'Baseball'
},
{
    id: 2,
    value: 9.99,
    label: 'Basketball'
}];

If there was only val = item.value at ng-click it won't update the val in the parent scope because of the isolated scope. That's why the parent scope is accessed with $parent reference or with the controllerAs syntax (e.g. ng-controller="mainController as ctrl").

Nested ng-repeat

You can also use nested ng-repeat.

<div ng-repeat="values in test">
    <div ng-repeat="i in values">
      [{{$parent.$index}},{{$index}}] {{i}}
    </div>
</div>

var app = angular.module("myApp", []);
app.controller("ctrl", function($scope) {
  $scope.test = [
    ['a', 'b', 'c'],
    ['d', 'e', 'f']
  ];
});

Here to access the index of parent ng-repeat inside child ng-repeat, you can use $parent.$index.