ng-repeat is my favorite of all the core AngularJS directives. A huge amount of front end programming time goes into displaying lists of things in helpful ways and ng-repeat helps make that easier, but it’s also filled to the brim with gotchas. Even worse, when something doesn’t work it fails silently and you’re left to figure out why your list isn’t sorting or filtering correctly.

Because of these gotchas, I put together a presentation last year for our Angular-Philly meetup titled, 14 Slides on ng-repeat. I frequently refer back to it to check my syntax so I figured it might be a useful blog post. Here are 8 features of ng-repeat!

Plain ng-repeat

Model

Template

View
Ben
Nate
Austin
Yiannis
Matt M
Matt B

Very simple. We have an array of strings and we’re creating an unordered list and populating each list item with a string from the names array. The data is bound to $scope and Angular keeps the model and the view consistent.

track by

Model

Template

View
Ben
Nate
Austin
Yiannis
Matt
Matt

Around Angular 1.3 they started requiring track by for any list that may include duplicate values. Using track by also speeds up list changes significantly. If you don’t use track by in this case, you get the error: Duplicates in a repeater are not allowed

filter

Model

Template

View

Matt M
Matt B

By binding the filter to the searchBox, you can create an easy way to find the list item you want. A common mistake is to put the filter after the track by like this. name in names track by $index | filter:searchBox. Don’t do it!

object

Model

Template

View
Ben true
Nate true
Austin false

Yes, you can iterate over objects with ng-repeat, but don’t do it! You’ll regret it. All the cool stuff like sorting and filtering either doesn’t work or gets way more complicated. If you’re iterating over an object with ng-repeat, you’ve already screwed up.

array of objects

Model

Template

View

Ben true

stacked filters

Model

Template

View

Ben true
Nate true

nested loops

Model

Template

View

Nate
Ben
Austin

order by

Model

Template

View

Austin
Ben
Nate

Don’t forget the orderBy value has to be a string. Don’t do this! ng-repeat="user in users | filter:searchBox:user.name | orderBy:name"

pipeline-ad-blog

  • Bala Abhinav

    You have mentioned that using key,value in ng-repeat is bad. But I have a situation where there is a json object with atleast 200 key, value pairs. What would you suggest is a better way to display them and make sure that there is two way data binding?

    • Ben Garvey

      If you have a simple situation, repeating over object keys is fine. The problem is that you lose access to some of the great features of ng-repeat. I have been in your situation before and to get around it, I have created a new array in the parent directive from the object keys.

      • Bala Abhinav

        Thanks for the reply. I did it by binding the value from the (key,value) to parent[key].. And it works great for now 😀

  • eric

    i noticed some ng-repeat using this “product in results = products” .. any idea why they did that? I still couldn’t figure out the reasons as inside the loop elements, they are using {{product.name}} .. how does the results come into this context? Thanks.

    • Ben Garvey

      eric,
      I’d have to see the full context to be sure, but it looks like they are using the expression to set the value of results in addition to using it as an iterator. It would make more sense to me if it was something where results was the value and they were setting the value of products for readability.

      If you change it to product in products does the code still function?

  • srikanth reddy

    As you said ,”ng-repeat with objects filters will not work & will work for array of objects” is this point correct which I stated from your article ? Because I can see in array of objects you had provided the filter as . Please confirm it ?

  • Padmapriya Vishnuvardhan

    Hi,
    I have key,value in list of ng-repeat, where key is holding some special character like $advance, so the ng-repeat is not looping through that particular object. Is there any way to handle this situation?