Joe82
Joe82

Reputation: 1251

Ng-repeat one element multiple times based on its properties

I have an object like this:

$scope.cars=[
    {'element':'Ford','count':3},
    {'element':'Honda','count':2},
    {'element':'Ferrari','count':1},
    {'element':'Delorean','count':6}
];

What I would like to achieve is to repeat every element n times where n is defined by its property count

I have achieved it like this

   <li ng-repeat="car in cars">
      <p2 ng-if="car.count >0">{{car.element}}</p2>
      <p2 ng-if="car.count >1">{{car.element}}</p2>
      <p2 ng-if="car.count >2">{{car.element}}</p2>
      <p2 ng-if="car.count >3">{{car.element}}</p2>
      <p2 ng-if="car.count >4">{{car.element}}</p2>
      <p2 ng-if="car.count >5">{{car.element}}</p2>
      <p2 ng-if="car.count >6">{{car.element}}</p2>
   </li>

but I would like to know if it is possible to do a general case in Angular (so I can apply it even if I don't know which number is going to appear in car.count)

You can check the plunkr here Thanks in advance!

Upvotes: 1

Views: 919

Answers (6)

There's a simple and pure JavaScript way:

<li ng-repeat="car in cars">
    <p2 ng-repeat="item in [].constructor(car.count) track by $index">{{car.element}}</p2>
</li>

Upvotes: 2

Jon
Jon

Reputation: 2671

You can go about it by adding a function in your app.js that displays the cars by count. So doing the following will give you your desired results:

in app.js

$scope.displayCarByCount = function(car) {
    var carString = '';
    for(var i= 0; i < car.count; i++) {
      carString += car.element + ' ';
    }
    return  carString;
 }

in HTML

<li ng-repeat="car in cars">
     <p2>{{displayCarByCount(car)}}</p2>
 </li>

Here is a plnkr in case you don't just want to read.

Upvotes: 0

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

You could create an array dynamically based on count provided by each car item. And then loop over that array and have :: just for evaluate createArray function binding only once.

Markup

<li ng-repeat="car in cars">
    <p2 ng-repeat="item in ::createArray(car.count) track by $index">{{car.element}}</p2>
</li>

Controller

$scope.createArray = function(count) {
    return new Array(count);
}

Demo Plunkr

Upvotes: 1

Teddy Sterne
Teddy Sterne

Reputation: 14201

You can use nested ng-repeat directives and a function that creates a new array of a specific length to acheive your desired result.

<li ng-repeat="car in cars">
    <p2 ng-repeat="t in arrayOfLength(car.count) track by $index">{{car.element}} </p2>
</li>

Controller

$scope.arrayOfLength = function(num){
    return new Array(num);
}

Working Plunkr

Upvotes: 2

Poyraz Yilmaz
Poyraz Yilmaz

Reputation: 5857

You can use another ng-repeat inside of you main ng-repeat and use a custom filter which returns empty array with a size of car.count...

<li ng-repeat="car in cars">
    <p2 ng-repeat="item in car | carCount track by $index">{{car.element}}</p2>
</li>

Here is our custom filter code carCount

app.filter('carCount', function() {
  return function (car) {
    return new Array(car.count);
  }
});

and here is your updated plunker

Upvotes: 1

Juan&#237;n
Juan&#237;n

Reputation: 851

You can do something like this:

<li ng-repeat="car in cars">
      <p2 ng-repeat="i in _.range(1,car.count)">{{car.element}}</p2>
</li>

And in your controller you have to add underscore (or a function that gives you a range) to the scope like this

$rootScope._ = _;

or

$scope.range = _.range

Upvotes: 1

Related Questions