Way to ng-repeat defined number of times instead of repeating over array?

406,593

Solution 1

Update (9/25/2018)

Newer versions of AngularJS (>= 1.3.0) allow you to do this with only a variable (no function needed):

<li ng-repeat="x in [].constructor(number) track by $index">
    <span>{{ $index+1 }}</span>
</li>
$scope.number = 5;

This was not possible at the time the question was first asked. Credit to @Nikhil Nambiar from his answer below for this update


Original (5/29/2013)

At the moment, ng-repeat only accepts a collection as a parameter, but you could do this:

<li ng-repeat="i in getNumber(number)">
    <span>{{ $index+1 }}</span>
</li>

And somewhere in your controller:

$scope.number = 5;
$scope.getNumber = function(num) {
    return new Array(num);   
}

This would allow you to change $scope.number to any number as you please and still maintain the binding you're looking for.

EDIT (1/6/2014) -- Newer versions of AngularJS (>= 1.1.5) require track by $index:

<li ng-repeat="i in getNumber(number) track by $index">
    <span>{{ $index+1 }}</span>
</li>

Here is a fiddle with a couple of lists using the same getNumber function.

Solution 2

you can do this:

<div ng-repeat="i in [1, 2, 3, 4]">
  ...
</div>

Solution 3

Here is an example of how you could do this. Note that I was inspired by a comment in the ng-repeat docs: http://jsfiddle.net/digitalzebra/wnWY6/

Note the ng-repeat directive:

<div ng-app>
    <div ng-controller="TestCtrl">
        <div ng-repeat="a in range(5) track by $index">{{$index + 1}}</div>
    </div>
</div>

Here is the controller:

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

Solution 4

I think this jsFiddle from this thread might be what you're looking for.

<div ng-app ng-controller="Main">
   <div ng-repeat="item in items | limitTo:2">
       {{item.name}}
   </div>
</div>

Solution 5

A simpler approach would be (for an example of 5 times):

<div ng-repeat="x in [].constructor(5) track by $index">
       ...
</div>
Share:
406,593
Malcr001
Author by

Malcr001

Updated on March 24, 2021

Comments

  • Malcr001
    Malcr001 about 3 years

    Is there a way to ng-repeat a defined number of times instead of always having to iterate over an array?

    For example, below I want the list item to show up 5 times assuming $scope.number equal to 5 in addition incrementing the number so each list item increments like 1, 2, 3, 4, 5

    Desired result:

    <ul>
       <li><span>1</span></li>
       <li><span>2</span></li>
       <li><span>3</span></li>
       <li><span>4</span></li>
       <li><span>5</span></li>
    </ul>
    
  • trevorc
    trevorc over 10 years
    read further down on the google thread link and it describes how you can use 'slice'. e.g. group1: items.slice(0,3), group2: items.slice(3,6), etc.
  • afternoon
    afternoon over 10 years
    You could also use _.range from Underscore or lodash to create the array: $scope.range = _.range(0, n);
  • Matt Jensen
    Matt Jensen over 10 years
    This answer will result in the most minimal footprint in your controllers and I believe is the preferred Angular approach as well. IMO accepted answer should be replaced with this.
  • jedd.ahyoung
    jedd.ahyoung about 10 years
    This is good, but note that Underscore isn't in scope by default - you wouldn't be able to use it in your HTML view without doing something like $scope._ = _.
  • Cody
    Cody about 10 years
    This should be the accepted answer (in my opinion) -- Most elegant, most ng-prefered.
  • Ivan Ferrer Villa
    Ivan Ferrer Villa almost 10 years
    did you use track by $index?
  • Dan
    Dan almost 10 years
    @Cody Unfortunately, no it does not answer the question. OP states "instead of always having to iterate over an array" and "assuming $scope.number equal to 5". The intent was to use an integer variable to define the item count, not hardcode it and not use a predefined array.
  • drzaus
    drzaus almost 10 years
    @Cody @sh0ber you can set the limit in your scope ($scope.limit = 2) and use it like ...|limitTo:limit -- see updated fiddle
  • Neara
    Neara over 9 years
    worked like a charm, tested on Chrome v. 39.0.2171.95 (64-bit), FF v. 33.1.1 and Safari v. 8.0.2
  • Rick
    Rick almost 9 years
    This works perfectly if you are using it in a pagination control where all you need is <li><a href="javascript:;" ng-click="SelectPage($index)">{{ i }}</a></li>
  • Jeremy Moritz
    Jeremy Moritz almost 9 years
    If you are using lodash or underscore, you should put it in $rootScope so it can be used everywhere. Put this in your app.run function just after the app.config: app.run(function ($rootScope) { $rootScope._ = _; });
  • Admin
    Admin over 8 years
    For those of you who like clean markup... Keep in mind using ng-repeat in this way will still output it's commented tags (<!-- ngIf: $index < num --> etc..). There simply won't be any li elements for the DOM to render. Check a "view source" on the results pane here to see what I mean.
  • trysis
    trysis over 8 years
    I believe this does not let you change the number of repeats in the HTML if it is changed in the controller, unless you wrap it in a function like other answers have done.
  • Manavendher
    Manavendher over 8 years
    $scope.getNumber = function(num) { var x=new Array(); for(var i=0;i<num;i++){ x.push(i+1); } return x; } //use this function when the number is changes dynamically
  • Dan
    Dan over 8 years
    @Manavendher Incorrect. We do not need to populate the array, we only need it to be the length of $scope.number. Angular's digest cycle will automatically recall this function and resize the array any time $scope.number changes.
  • Manavendher
    Manavendher over 8 years
    @sh0ber. When I need to change the list items based on the value selected in number dropdown. I tried your function first, when it is not working, I changed it to above to update the no. of list items when different number is selected in the dropdown. Can you please check my scenario using your function.
  • Darryl
    Darryl over 8 years
    This was a perfect answer for me. It's simple and very straightforward. Since I was repeating using a variable that had a count, I had to do ng-repeat="n in _.range(1, count+1). Thanks for the solution.
  • Paul
    Paul about 8 years
    I tried this and while _ shows up in $rootScope, the ng-repeat doesn't render anything.
  • azerafati
    azerafati almost 8 years
    @AdityaMP, use this for ranges in javascript stackoverflow.com/a/31989462/3160597
  • James Drinkard
    James Drinkard almost 8 years
    I had a requirement to limit the list to the first three items, then have a modal if the user wanted the entire list. Using this example I got it working. Thanks!
  • jannis
    jannis over 7 years
    Best hack ever! Thanks
  • JellicleCat
    JellicleCat over 7 years
    @trysis : I'm not sure if I understand your issue, but you should replace repeatCount with an actual number in the HTML, and as long as that number is less-than-or-equal-to MAX_REPEATS, this will let you set the number of repeats in the HTML.
  • HalfWebDev
    HalfWebDev over 7 years
    @Manavendher I tried with angular 1.2.x and 1.5.x with same results. Links are 1. stackoverflow.com/questions/40202263/… 2. plnkr.co/edit/zcPr7oUEBBWvCSVkDvml
  • Roi
    Roi over 7 years
    this is ghetto af. if you're going to be forced to have a char for each iteration you might as well do ng-repeat="i in [1,2,3,4]"
  • Ivan Ferrer Villa
    Ivan Ferrer Villa over 7 years
    of course, but OP wants the iteration to be n times based on a variable $scope.number
  • Julien Malige
    Julien Malige over 7 years
    up to date (2016) and much cleaner !
  • Fabricio
    Fabricio over 7 years
    _ in (_ = []).length = 33; _ track by $index slightly smaller
  • Pat Migliaccio
    Pat Migliaccio about 7 years
    In my opinion, this is the most elegant way of limiting the ngRepeat directive. Using Array.prototype.slice and idiomatic JS should always be chosen over a library like underscore.js (browser compatibility depending).
  • HarshaXsoad
    HarshaXsoad almost 7 years
    This is something they should consider adding to official angular directives
  • maxathousand
    maxathousand over 6 years
    Brilliant. Readable, short, and no silly functions in the controller to return a new array.
  • maxathousand
    maxathousand over 6 years
    Consider calling the array constructor for a dynamic-length array, as stated in this answer.
  • maxathousand
    maxathousand over 6 years
    Not a bad solution, +1, but I think this answer is easier, and avoids cluttering the controller.
  • Rabbi Shuki Gur
    Rabbi Shuki Gur over 6 years
    I Love this way.
  • omikes
    omikes over 6 years
    why not 'abcd' instead of 'aaaa' and then scrap the track by?
  • omikes
    omikes over 6 years
    i believe the split is unnecessary here. a string is already an array of characters.
  • Ivan Ferrer Villa
    Ivan Ferrer Villa over 6 years
    aaaa was an example to explain my -not very elegant- workaround. Using hardcoded 'aaaa' or 'abcd' you get a fixed length list, but adding mynumber-2 decimals to 0, you get a 'string' with mynumber chars. Say mynumber=5, you get '0.000', then we iterate that using $index
  • Dylan Nicholson
    Dylan Nicholson over 5 years
    I just wish I understood why this syntax works but not Array(5) (or indeed [...Array(5).keys()] to get an array [0,1,2,3,4])
  • Munkhdelger Tumenbayar
    Munkhdelger Tumenbayar about 4 years
    what if i have to repeat 120 times. Should i go with [1,2,3... 120]?