Ng-repeat on integer value

33,149

Solution 1

Checkout this

<div ng-app='myApp' ng-controller="Main">
  <span ng-repeat="n in range('5')">Start{{$index}} &nbsp;&nbsp;</span>
</div>

$scope.range = function(count){

  var ratings = []; 

  for (var i = 0; i < count; i++) { 
    ratings.push(i) 
  } 

  return ratings;
}

Change your html to following

<div id="pie-list-wrapper">
  <ul class="nav">
    <a href="#/pies/pieid" ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp">
      <li class="list-item rounded-corners box-shadow">
        <aside>
          <img src="{{pie.imageUrl}}" no-repeat alt="Image of the pie">
        </aside>
        <header>
          <h1 ng-bind="pie.name" id="item-name" class="bold-text"></h1>
        </header>
        <article>
          <span ng-bind="pie.description" id="item-desc"></span>
        </article>
        <footer id="item-rating">
          <div ng-repeat="start in range(pie.rating)" class="rating-box"></div> //Contains the stars
        </footer>
      </li>
    </a>
  </ul>
</div>

Solution 2

I solved this in this way: "items" is your array of objects in the $scope, accesing the property "rating", you can show the star if the value is less or the same comparing to the "rating" property.

In this example I'm using some icon fonts but for the case of an image is the same thing.

<div ng-repeat="item in items">
    <div class="item-offers"">
        <img ng-src="{{item.image}}">
        <div class="item-not-rating">
            <i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 1"></i>
            <i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 2"></i>
            <i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 3"></i>
            <i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 4"></i>
            <i class="icon ion-ios-star icon-rating" ng-if="item.rate >= 5"></i>
        </div>                        
    </div>
</div>

I've found a better solution that solves this requirement at all:

https://github.com/fraserxu/ionic-rating

Solution 3

It looks like you are iterating on the pies and that's where the $index gets its value from. Instead of ng-repeat="rating in ratings[$index]" you should use ng-repeat="rating in range(pie.rating)" This way, the rating would follow your pie when ordering. Then you could completely remove the loop in the controller.

Could you provide just a bit more HTML so that we could see where the $index comes from?

Regards, Camusensei

EDIT: You are indeed iterating over pies.pies in ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp" So what I wrote earlier should work. See below for exhaustive changes.

Controller:

$http.get('jsons/pies.json')
     .success(function(data, status) {
        $scope.pies = data;
     })
     .error(function(status) {
        console.log(status);
     })

HTML:

<div ng-repeat="rating in range(pie.rating)" class="rating-box"></div>

EDIT2: Sorry, I forgot the range function (inspired from Ariya Hidayat):

$scope.range = function(count){
    return Array.apply(0, Array(+count));
}

Solution 4

The problem is that ng-repeat only works with arrays or objects, so you can't say iterate x times (while x is a number)

A solution could be to write a function in JavaScript:

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

An then use this html to show the stars without $index:

<div ng-repeat="rating in getNumber(pie.rating)"></div> 
Share:
33,149
Chrillewoodz
Author by

Chrillewoodz

I love green numbers.

Updated on July 05, 2022

Comments

  • Chrillewoodz
    Chrillewoodz almost 2 years

    I'm trying to use ng-repeat on a div which should contain a star image, each pie in the JSON has a rating property from 1-5, and I want to use this value to loop out x number of stars. I've got this working somewhat but it's flawed in the way that I can't re-sort the array and make the stars follow the correct item in the list since I'm using [$index] to track the iteration.

    My solution is rather ugly as well since I'm creating arrays with as many index placeholders as the value of the rating property, and then pushing this into an array to loop out the appropriate number of images. I would like to have a more elegant solution.

    How should I go about this problem without using [$index]?

    Snippet of the JSON:

    {"pies": [
        ...
    
        {
            "name": "Blueberry pie", 
            "imageUrl": "img/blueberrypie.png", 
            "id": "1",
            "rating": "5", //Ng-repeat depending on this value
            "description": "Blueberry pie is amazing."
        },
    
        ...
    ]}
    

    My controller:

    pieShopApp.controller('shopCtrl', ['$scope', '$http', '$routeParams', function ($scope, $http, $routeParams) {
        $scope.pieId = $routeParams.pieId,
        $scope.sortingOptions = ['A-Z', 'Rating'],
        $scope.sortingValues = ['name', 'rating'],
        $scope.ratings = [],
        $http.get('jsons/pies.json')
             .success(function(data, status) {
                $scope.pies = data;
    
                for (i = 0; i < $scope.pies.pies.length; i++) {
    
                    switch ($scope.pies.pies[i].rating) {
    
                        case "1": $scope.ratings.push(["1"]); break;
    
                        case "2": $scope.ratings.push(["1", "2"]); break;
    
                        case "3": $scope.ratings.push(["1", "2", "3"]); break;
    
                        case "4": $scope.ratings.push(["1", "2", "3", "4"]); break;
    
                        case "5": $scope.ratings.push(["1", "2", "3", "4", "5"]); break;
                    }
                }
                console.log($scope.ratings);
             })
             .error(function(status) {
                console.log(status);
             })
    }]);
    

    The list which contains the pie items:

    <div id="pie-list-wrapper">
        <ul class="nav">
            <a href="#/pies/pieid" ng-repeat="pie in pies.pies | filter:query | orderBy:orderProp">
                <li class="list-item rounded-corners box-shadow">
                    <aside>
                        <img src="{{pie.imageUrl}}" no-repeat alt="Image of the pie">
                    </aside>
                    <header>
                        <h1 ng-bind="pie.name" id="item-name" class="bold-text"></h1>
                    </header>
                    <article>
                        <span ng-bind="pie.description" id="item-desc"></span>
                    </article>
                    <footer id="item-rating">
                        <div ng-repeat="rating in ratings[$index]" class="rating-box"></div> //Contains the stars
                    </footer>
                </li>
            </a>
        </ul>
    </div>
    

    Outcome:

    pies list

  • Chrillewoodz
    Chrillewoodz over 9 years
    How do I pass the current rating value as a parameter though?
  • dhavalcengg
    dhavalcengg over 9 years
    edited my answer. Now you don't need ratings array. Just pass pie.rating to range function. And you are good to go.
  • Chrillewoodz
    Chrillewoodz over 9 years
    Hmm.. I got a bit of an odd one. When using +count I get no stars at all, if I use count I only get one. Any idea why? My solution is identical to yours.
  • dhavalcengg
    dhavalcengg over 9 years
    use other variable then rating in ng-repeat. Updated my answer.
  • Chrillewoodz
    Chrillewoodz over 9 years
    Look at my comment in the answer above.
  • dhavalcengg
    dhavalcengg over 9 years
    This could happen if your pie.rating is blank string. Can you check pie.rating again.?
  • Chrillewoodz
    Chrillewoodz over 9 years
    Just thought of that. Testing to see when integer hang on.
  • Chrillewoodz
    Chrillewoodz over 9 years
    Doesn't work at all when it's a number... What exactly does the + before count do?
  • dhavalcengg
    dhavalcengg over 9 years
  • Camusensei
    Camusensei over 9 years
    For debug purposes, use this range function: $scope.range = function(count){var a = new Array(+count); console.log(count, a); return a;};
  • Chrillewoodz
    Chrillewoodz over 9 years
    We solved it, still doesn't know what caused it to malfunction though. I will investigate this matter further.
  • Camusensei
    Camusensei over 9 years
    Okay, I found out where the problem was : 2ality.com/2012/06/dense-arrays.html The array was sparse instead of dense
  • Chrillewoodz
    Chrillewoodz over 9 years
    Interesting, but I tried that solution but didn't work either. It feels like there's something else that's causing the malfunction. At least I've found a solution that works now ;S
  • Camusensei
    Camusensei over 9 years
    Ok great ^^ Have a nice day.
  • alphapilgrim
    alphapilgrim over 8 years
    how would you add a class to this?