---
description: In this tutorial, we will learn What is AngularJS ng-repeat Directive with an Example and How to define Multiple Controllers in AngularJS Applications.
title: AngularJS ng-repeat Directive with Example
image: https://www.guru99.com/images/angularjs-ng-repeat-directive.png
---

 

[Skip to content](#main) 

**⚡ Smart Summary**

The ng-repeat directive in AngularJS renders one copy of an element for every item in a collection defined on the controller scope. It turns an array into a list, a table, or any repeating markup without writing a manual loop.

* 🔁 **Core Behaviour:** ng-repeat clones its host element once per item, so the directive belongs on the element being repeated, not its container.
* 🏷️ **Loop Variable:** The name before the word in becomes a local alias for the current item inside that clone.
* 🧬 **Child Scope:** Every iteration receives its own child scope, which is why assigning a primitive inside the loop does not reach the parent.
* 🔑 **Identity Tracking:** A track by expression tells AngularJS how to identify items, and it is required when a collection holds repeated values.
* 🔢 **Built-in Locals:** Properties such as $index, $first, and $last are available inside each iteration for numbering and styling.
* ⚠️ **Support Status:** AngularJS reached end of life on 31 December 2021 and receives no further security patches.

[ Read More ](javascript:void%280%29;) 

![AngularJS ng-repeat Directive](https://www.guru99.com/images/angularjs-ng-repeat-directive.png)

## ng-repeat Directive in AngularJS

The **ng-repeat** [directive](https://www.guru99.com/angularjs-directive.html) in AngularJS is used to display repeating values defined in the controller. Sometimes we need to show a list of items in the view, and ng-repeat renders a list defined in the controller onto a view page.

**⚠️ Support notice:** AngularJS reached **end of life on 31 December 2021** and receives no further patches or security fixes. The directive below remains accurate for maintaining existing AngularJS 1.x applications; in modern [Angular](https://www.guru99.com/react-vs-angular-key-difference.html) the equivalent is the `*ngFor` structural directive.

### AngularJS ng-repeat Directive Example

Let us look at an example of the ng-repeat directive in AngularJS:

[![ng-repeat Directive in AngularJS](https://www.guru99.com/images/AngularJS/010416_0650_AngularJSCo15.png)](https://www.guru99.com/images/AngularJS/010416%5F0650%5FAngularJSCo15.png)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp" ng-controller="DemoController">
    <h1>Topics</h1>
    <ul>
        <li ng-repeat="tpname in TopicNames">
            {{tpname.name}}
        </li>
    </ul>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('DemoController', function($scope) {
        $scope.TopicNames = [
            { name: "What controllers do from Angular's perspective" },
            { name: "Controller Methods" },
            { name: "Building a basic controller" }
        ];
    });
</script>

</body>
</html>

**Code Explanation:**

1. In the [controller](https://www.guru99.com/angularjs-controller.html), we first define the array of list items to be shown in the view. Here an array called `TopicNames` holds three items, each a name-value pair.
2. The array is assigned directly to `$scope.TopicNames`, which makes it available to the view bound to this controller.
3. The HTML tags `<ul>` (unordered list) and `<li>` (list item) display the items. The ng-repeat directive iterates over each entry in the array, and `tpname` is the local variable holding the current item, so `{{tpname.name}}` prints its name property.

**⚠️ Correction:** the original explanation stated that the array was “added to a member variable called `topics`“. No such variable exists in the code — the array is assigned straight to `$scope.TopicNames`, which is the name the view refers to. Introducing a second name here is a common cause of an empty list.

If the code is executed successfully, the following output is shown in the browser.

[![ng-repeat Directive in AngularJS](https://www.guru99.com/images/AngularJS/010416_0650_AngularJSCo16.png)](https://www.guru99.com/images/AngularJS/010416%5F0650%5FAngularJSCo16.png)

## AngularJS Multiple Controllers

Earlier we saw a single controller in which one method handled both addition and subtraction of numbers. You can instead use multiple controllers to separate logic more cleanly. For example, one controller can operate on numbers while another operates on strings.

Let us look at an example of defining multiple controllers in an AngularJS application.

[![AngularJS Multiple Controllers](https://www.guru99.com/images/AngularJS/010416_0650_AngularJSCo17.png)](https://www.guru99.com/images/AngularJS/010416%5F0650%5FAngularJSCo17.png)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp">
    <div ng-controller="firstcontroller">
        <div ng-controller="secondcontroller">
            {{lname}}
        </div>
    </div>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('firstcontroller', function($scope) {
        $scope.pname = "firstcontroller";
    });

    app.controller('secondcontroller', function($scope) {
        $scope.lname = "secondcontroller";
    });
</script>

</body>
</html>

**Code Explanation:**

1. Two controllers are defined, `firstcontroller` and `secondcontroller`. Each attaches a variable to its own [scope](https://www.guru99.com/angularjs-scope.html): `pname` in the first, `lname` in the second.
2. In the view, the second controller is nested inside the first, and the expression reads `lname` from the inner scope. Because a nested controller inherits from its parent, `{{pname}}` would also resolve here — inheritance flows downward, never upward.

If the code is executed successfully, the text _secondcontroller_ is displayed.

[![AngularJS Multiple Controllers](https://www.guru99.com/images/AngularJS/010416_0650_AngularJSCo18.png)](https://www.guru99.com/images/AngularJS/010416%5F0650%5FAngularJSCo18.png)

### RELATED ARTICLES

* [How to use “ng-model” in AngularJS with EXAMPLES ](https://www.guru99.com/ng-model-angularjs.html "How to use “ng-model” in AngularJS with EXAMPLES")
* [AngularJS ng-view with Example ](https://www.guru99.com/angularjs-views.html "AngularJS ng-view with Example")
* [AngularJS Dependency Injection Components ](https://www.guru99.com/angularjs-dependency-injection.html "AngularJS Dependency Injection Components")
* [Protractor Testing Tutorial: Automation Tool Framework ](https://www.guru99.com/protractor-testing.html "Protractor Testing Tutorial: Automation Tool Framework")

## How to Use track by with ng-repeat

The single most common ng-repeat failure is the error `Duplicates in a repeater are not allowed`. It appears the moment a collection contains the same value twice, and it stops the list rendering entirely.

The cause is identity tracking. AngularJS needs a stable key for each item so that it can reuse DOM nodes rather than rebuild them on every digest. By default it uses the item value itself, so two identical values collide.

<!-- Fails: the value 2 appears twice -->
<li ng-repeat="n in [1, 2, 2, 3]">{{n}}</li>

<!-- Works: position is unique even when values repeat -->
<li ng-repeat="n in [1, 2, 2, 3] track by $index">{{n}}</li>

<!-- Best for records from a server: track by a real identifier -->
<li ng-repeat="topic in TopicNames track by topic.id">{{topic.name}}</li>

Choosing between the two forms matters more than it first appears. Tracking by `$index` always resolves the error, because a position is unique by definition, but it ties each DOM node to a slot rather than to a record. Reordering or filtering the collection then reuses the wrong nodes, which shows up as input fields keeping the previous row’s text.

Tracking by a genuine identifier such as `topic.id` avoids that entirely. AngularJS can follow each record as it moves, so it reorders existing nodes instead of destroying and rebuilding them. On long lists this is also markedly faster, since a re-render touches only the rows that actually changed. Use `$index` only for arrays of plain values that never reorder.

## Special Properties Available Inside ng-repeat

Each iteration of ng-repeat exposes several read-only properties on its own child scope. They describe where the current item sits within the collection, which covers numbering, alternating styles, and separators without adding any extra state to the controller.

| Property | Type    | Value                                              |
| -------- | ------- | -------------------------------------------------- |
| $index   | Number  | Position of the current item, starting at 0        |
| $first   | Boolean | True for the first item only                       |
| $last    | Boolean | True for the last item only                        |
| $middle  | Boolean | True for every item that is neither first nor last |
| $even    | Boolean | True when $index is even                           |
| $odd     | Boolean | True when $index is odd                            |

A typical use combines them with ng-class for zebra striping, as in `ng-class="{'row-alt': $odd}"`, or with ng-if to render a separator on every row except the last, written `ng-if="!$last"`. Displaying a human-readable row number is simply `{{$index + 1}}`, since the index is zero-based. All six properties are recalculated automatically whenever the collection changes, so nothing needs to be recomputed by hand.

## Common ng-repeat Errors and How to Fix Them

Most ng-repeat problems come from duplicate values, from scope inheritance, or from the directive sitting on the wrong element. Each symptom below names its cause.

* **Duplicates in a repeater are not allowed:** the collection holds a repeated value. Add `track by $index`, or better, `track by` a unique property.
* **The list renders nothing:** the name in the view does not match the property on the scope. Print the collection with `{{TopicNames}}` to confirm it arrived.
* **Every element repeats, including the wrapper:** ng-repeat was placed on the container rather than on the item. Move it to the `<li>` or `<tr>`.
* **Editing an input changes the wrong row:** the list is tracked by `$index` while items reorder. Track by a stable identifier instead.
* **Changes inside the loop do not persist:** each iteration has its own child scope, so writing to a primitive creates a local copy. Write to an object property, such as `item.done`.

## FAQs

🗂️ Can ng-repeat iterate over an object instead of an array?

Yes, using `ng-repeat="(key, value) in myObject"`. Note that AngularJS iterates object keys in sorted order, not insertion order, so an array is safer when sequence matters.

🔍 How do you filter or sort the repeated list?

Chain filters in the expression, as in `ng-repeat="t in TopicNames | filter:search | orderBy:'name'"`. The original array is untouched; only the rendered order and subset change.

🤖 Can AI convert ng-repeat to Angular ngFor?

Yes. [AI](https://www.guru99.com/ai-tutorial.html) tools map ng-repeat to `*ngFor` and track by to trackBy functions. Check filters carefully, because Angular deliberately dropped the built-in filter and orderBy pipes.

🧠 How does AI help when a repeated list renders slowly?

AI tools spot function calls inside the repeat expression, which re-run on every digest, and missing track by clauses that force full DOM rebuilds. Both are the usual causes of a sluggish list.

📑 How do you repeat without adding a wrapper element?

Use the comment form, `ng-repeat-start` and `ng-repeat-end`, which repeats a range of sibling elements. This matters in tables, where an extra div would break the markup.

#### Summarize this post with:

ChatGPT Perplexity Grok Google AI 

**Stay Updated on AI** **Get Weekly AI Skills, Trends, Actionable Advice.** 

##### Sign up for the newsletter

Subscribe for Free 

You have successfully subscribed.  
Please check your inbox. 

![AI-Newsletter](https://www.guru99.com/images/footer-email-avatar-imges-1.png) Chosen by over **350,000+** professionals 

[Scroll to top ](#wrapper)Scroll to top 

× 

Toggle Menu Close 

Search for: 

Search

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://www.guru99.com/#organization","name":"Guru99","sameAs":["https://www.facebook.com/Guru99Official","https://twitter.com/guru99com"],"logo":{"@type":"ImageObject","@id":"https://www.guru99.com/#logo","url":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","contentUrl":"https://www.guru99.com/images/guru99-logo-v1-150x59.png","caption":"Guru99","inLanguage":"en-US"}},{"@type":"WebSite","@id":"https://www.guru99.com/#website","url":"https://www.guru99.com","name":"Guru99","publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https://www.guru99.com/images/angularjs-ng-repeat-directive.png","url":"https://www.guru99.com/images/angularjs-ng-repeat-directive.png","width":"700","height":"250","caption":"AngularJS ng-repeat Directive","inLanguage":"en-US"},{"@type":"BreadcrumbList","@id":"https://www.guru99.com/angularjs-ng-repeat.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","item":{"@id":"https://www.guru99.com","name":"Home"}},{"@type":"ListItem","position":"2","item":{"@id":"https://www.guru99.com/angularjs","name":"AngularJS"}},{"@type":"ListItem","position":"3","item":{"@id":"https://www.guru99.com/angularjs-ng-repeat.html","name":"AngularJS ng-repeat Directive with Example"}}]},{"@type":"WebPage","@id":"https://www.guru99.com/angularjs-ng-repeat.html#webpage","url":"https://www.guru99.com/angularjs-ng-repeat.html","name":"AngularJS ng-repeat Directive with Example","dateModified":"2026-07-30T19:25:15+05:30","isPartOf":{"@id":"https://www.guru99.com/#website"},"primaryImageOfPage":{"@id":"https://www.guru99.com/images/angularjs-ng-repeat-directive.png"},"inLanguage":"en-US","breadcrumb":{"@id":"https://www.guru99.com/angularjs-ng-repeat.html#breadcrumb"}},{"@type":"Person","@id":"https://www.guru99.com/author/james","name":"James Hartman","description":"I am James Hartman, a seasoned professional in Oracle Certified Java Professional tutorials, specializing in crafting comprehensive guides to help you excel in your Java certification journey.","url":"https://www.guru99.com/author/james","image":{"@type":"ImageObject","@id":"https://www.guru99.com/images/james-hartman-author-v2-120x120.png","url":"https://www.guru99.com/images/james-hartman-author-v2-120x120.png","caption":"James Hartman","inLanguage":"en-US"},"worksFor":{"@id":"https://www.guru99.com/#organization"}},{"articleSection":"AngularJS","headline":"AngularJS ng-repeat Directive with Example","description":"In this tutorial, we will learn What is AngularJS ng-repeat Directive with an Example and How to define Multiple Controllers in AngularJS Applications.","keywords":"angularjs","speakable":{"@type":"SpeakableSpecification","cssSelector":[".entry-title",".summary"]},"@type":"Article","author":{"@id":"https://www.guru99.com/author/james","name":"James Hartman"},"dateModified":"2026-07-30T19:25:15+05:30","image":{"@id":"https://www.guru99.com/images/angularjs-ng-repeat-directive.png"},"copyrightYear":"2026","name":"AngularJS ng-repeat Directive with Example","subjectOf":[{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"Can ng-repeat iterate over an object instead of an array?","acceptedAnswer":{"@type":"Answer","text":"Yes, using ng-repeat=\"(key, value) in myObject\". Note that AngularJS iterates object keys in sorted order, not insertion order, so an array is safer when sequence matters."}},{"@type":"Question","name":"How do you filter or sort the repeated list?","acceptedAnswer":{"@type":"Answer","text":"Chain filters in the expression, as in ng-repeat=\"t in TopicNames | filter:search | orderBy:'name'\". The original array is untouched; only the rendered order and subset change."}},{"@type":"Question","name":"Can AI convert ng-repeat to Angular ngFor?","acceptedAnswer":{"@type":"Answer","text":"Yes. AI tools map ng-repeat to *ngFor and track by to trackBy functions. Check filters carefully, because Angular deliberately dropped the built-in filter and orderBy pipes."}},{"@type":"Question","name":"How does AI help when a repeated list renders slowly?","acceptedAnswer":{"@type":"Answer","text":"AI tools spot function calls inside the repeat expression, which re-run on every digest, and missing track by clauses that force full DOM rebuilds. Both are the usual causes of a sluggish list."}},{"@type":"Question","name":"How do you repeat without adding a wrapper element?","acceptedAnswer":{"@type":"Answer","text":"Use the comment form, ng-repeat-start and ng-repeat-end, which repeats a range of sibling elements. This matters in tables, where an extra div would break the markup."}}]}],"@id":"https://www.guru99.com/angularjs-ng-repeat.html#schema-1156527","isPartOf":{"@id":"https://www.guru99.com/angularjs-ng-repeat.html#webpage"},"publisher":{"@id":"https://www.guru99.com/#organization"},"inLanguage":"en-US","mainEntityOfPage":{"@id":"https://www.guru99.com/angularjs-ng-repeat.html#webpage"}}]}
```
