88

How can I use ng-repeat like for in Javascript?

example:

<div ng-repeat="4">Text</div>

I want to iterate with ng-repeat 4 times but how can I do it?

Vural
  • 8,666
  • 11
  • 40
  • 57
  • 3
    Both are possible:Directives have camel cased names such as ngBind. The directive can be invoked by translating the camel case name into snake case with these special characters :, -, or _. Optionally the directive can be prefixed with x-, or data- to make it HTML validator compliant. – asgoth Jan 07 '13 at 15:23
  • 2
    wow how come so many wrong answers, you should use ng-repeat="item in items|limitTo:4" – Toolkit Jun 09 '15 at 03:36
  • There is a chance that he hasn't got any array to iterate over. Say, to display the stars in a star rating. There may be a field for how many stars you need to display, but this is not iterable. – nirazul Nov 02 '15 at 16:07
  • @Toolkit ... and what is `items`..? – T J Mar 04 '16 at 11:10
  • @TJ http://stackoverflow.com/a/17736076/631527 – Toolkit Mar 04 '16 at 11:20
  • @Toolkit that answer is about a filter called `limitTo`. My question was *what is `items`* because OP's problem is that he doesn't have an `items` array to give `ng-repeat` (or any filter), but only an integer. – T J Mar 04 '16 at 11:55

7 Answers7

344

Angular comes with a limitTo:limit filter, it support limiting first x items and last x items:

<div ng-repeat="item in items|limitTo:4">{{item}}</div>
David Lin
  • 13,168
  • 5
  • 46
  • 46
  • 14
    This should be the answer, as it also works with iterating over objects in an array. Plus its a Angular feature. – Ashley Coolman May 22 '14 at 23:41
  • 30
    This is an incredibly useful piece of code, but this does not actually satisfy the OP's question. He is simply looking for a way to repeat n times, and likely doesn't have an actual object to iterate over. – SamHuckaby Oct 16 '14 at 16:05
  • 2
    this should be the answer, it uses the tools provided by AngularJS core – Udo Jan 20 '15 at 12:29
  • This is the Strait Forward one with out pain ... Thank you DavidLin!! – Prasad Apr 09 '15 at 06:30
  • 10
    This doesn't actually solve the problem. You're assuming he has an object named `items` – Batman Dec 21 '15 at 05:38
  • Why are you not the answer. Get up there ^ – AJ_ Jan 19 '16 at 17:23
  • 1
    Not an useful answer for the question indeed (I googled specifically how to iterate X times, and not limit X) but useful piece of code nonetheless. – MacK Mar 31 '16 at 10:56
  • Hi, please note this answer was submitted in 2013. I might not be as helpful as it was before. – David Lin Apr 01 '16 at 03:16
65

This is the simplest workaround I could think of.

<span ng-repeat="n in [].constructor(5) track by $index">
{{$index}}
</span>

Here's a Plunker example.

ChandrasekarG
  • 1,384
  • 13
  • 24
  • 2
    Clever and very useful without using any function in the controller sitting around. Still baffled why this isn't an angular feature – MacK Mar 31 '16 at 10:59
  • 1
    This should be the *answer*. OP asked for "using ng-repeat like for". This implies having all of the implementation directly in the view, without any "assist" from the controller. This solution does exactly that...and is bloody clever to boot. – karfus Aug 24 '16 at 12:31
  • Nice, but does not work on all angular versions. I'm using 1.2.9 and it's not supported: `Error: [$parse:isecfld]` – Emaborsa Sep 06 '16 at 10:26
50

You can use slice method in javascript array object

<div ng-repeat="item in items.slice(0, 4)">{{item}}</div>

Short n sweet

Gihan
  • 4,163
  • 6
  • 31
  • 49
  • 2
    why it is wrong?. It works. Let's take another scenario, if you want array elements from 2 to 4 from array indexes. Does it work with limitTo filter? – Gihan Jun 15 '15 at 05:22
  • 4
    It's not wrong its just isnt as easy as `item in items|limitTo:4` – jofftiquez Jun 23 '15 at 07:43
  • 1
    This adds the functionality that I could show items 1-4, then click a button to change .slice(0,4) to .slice(5,8), allowing for a simple paginator. Thanks! – BaneStar007 May 02 '18 at 01:33
39

in the html :

<div ng-repeat="t in getTimes(4)">text</div>

and in the controller :

$scope.getTimes=function(n){
     return new Array(n);
};

http://plnkr.co/edit/j5kNLY4Xr43CzcjM1gkj

EDIT :

with angularjs > 1.2.x

<div ng-repeat="t in getTimes(4) track by $index">TEXT</div>
mpm
  • 20,148
  • 7
  • 50
  • 55
  • 20
    other options: `t in [1,2,3,4]` or `t in 'aaaa'` etc :) – Valentyn Shybanov Jan 07 '13 at 15:46
  • 4
    Seems odd that Angular can't support a mathematical loop without requiring a function to back it. – Guido Anselmi Jan 09 '14 at 03:00
  • 4
    Yeah I can imagine having to iterate 30x, writing it like `[1,2,3,4]`.. What a dismal solution this one – Matej Jan 15 '14 at 19:07
  • 2
    See below answer by DavidLin for a better solution. – SamHuckaby Oct 14 '14 at 14:44
  • @SamHuckaby the issue is iterating over a range.limitTo is useless in that case. It's not about iterating over a set of values that mean something on their own,it's iterating 4 times for instance.not 4 times over a slice of an existing array,just 4 times. just like in coffeescript when you create an adhoc slice , like "[0..4]" ,you dont really care about the actual values,just that you'll repeat an operation 4 times. – mpm Oct 15 '14 at 10:02
  • @mpm You're right, after re-reading the OP's question, I see what you mean. While the OP's question isn't a really good way to utilize ng-repeat, this answer does do the best job of fulfilling the specific request. – SamHuckaby Oct 16 '14 at 16:04
  • This answer is not working anymore!!! Simply use DavidLin's answer which works perfectly. –  Dec 23 '15 at 13:08
  • It is an old thread but to avoid duplicate question I am asking here. @mpm your solution works perfectly in my case but actually i need to add some data to it afterward, how can I add data to this array (in existing indexes or append new one) – Haris May 19 '16 at 06:20
13

Answer given by @mpm is not working it gives the error

Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}

To avoid this along with

ng-repeat="t in getTimes(4)"

use

track by $index

like this

&LT;div ng-repeat="t in getTimes(4) track by $index"&GT;TEXT&LT;/div&GT;

Pratik Goenka
  • 2,321
  • 1
  • 27
  • 24
  • my technique worked with the version of angularjs I used.Just check the plunkr, i'll update it asap. – mpm Oct 15 '14 at 10:07
10

To repeat 7 times, try to use a an array with length=7, then track it by $index:

<span ng-repeat="a in (((b=[]).length=7)&&b) track by $index" ng-bind="$index + 1 + ', '"></span>

b=[] create an empty Array «b»,
.length=7 set it's size to «7»,
&&b let the new Array «b» be available to ng-repeat,
track by $index where «$index» is the position of iteration.
ng-bind="$index + 1" display starting at 1.

To repeat X times:
just replace 7 by X.

funnyniko
  • 119
  • 1
  • 3
  • Unclear as to what this answer provides that isn't already covered by the accepted answer, or the two higher votes ones. – JamesT Feb 05 '15 at 10:28
  • Nothing more than how powerfull Angular can be. – funnyniko Feb 07 '15 at 10:57
  • 3
    The two higher votes answers seem to assume that «items» is an array. This one make the array in place. – funnyniko Feb 07 '15 at 11:09
  • Well done, it works. This is the only solution that actually addresses the OP's question. It's amazing that it only has a few votes. I just wonder if there is a more elegant solution. – Healforgreen Jan 26 '16 at 19:22
3

All answers here seem to assume that items is an array. However, in AngularJS, it might as well be an object. In that case, neither filtering with limitTo nor array.slice will work. As one possible solution, you can convert your object to an array, if you don't mind losing the object keys. Here is an example of a filter to do just that:

myFilter.filter('obj2arr', function() {
    return function(obj) {
        if (typeof obj === 'object') {
            var arr = [], i = 0, key;
            for( key in obj ) {
                arr[i] = obj[key];
                i++;
            }
            return arr;
        }
        else {
            return obj;
        }

    };
});

Once it is an array, use slice or limitTo, as stated in other answers.

Per Quested Aronsson
  • 11,380
  • 8
  • 54
  • 76