0

So I know that there a various questions regarding this issue on SO. I have checked loads of them and tried various combinations and I still can't get my directive to render.

Essentially I am trying to pass an integer to my directive in an ng-repeat and have it render an emoji based on the number.

The problem is that that scope.userpoints variable is undefined in the template but not in the link function...

This is the html. Note that both $scope.favourites and fav.update are populated asynchronously

<div ng-repeat="fav in favourites">
    <dencity-rank userpoints="fav.update.poster.points"></dencity-rank>
</div>

and this is the directive code

.directive('dencityRank', [function(){

  Number.prototype.between = function (min, max) {
    return this >= min && this <= max;
  };

  var getEmojiRank = function(points){

    console.log(points);
    if(typeof(points) === "undefined") return;

    if (points < 3) return "em-hatched_chick";
    else if (points.between(4, 8)) return "em-hatched_chick";
    else if (points.between(9, 14)) return "em-baby_chick";
    else return "em-hatched_chick";

  };

  return {
    scope: {
      userpoints: '=',
    },  // use a new isolated scope that does not inherit from parent
    restrict: "E", // use as html element
    replace: false, // replace the directive with the result of the directive?
    template: function(scope){
      return '<i class= "em ' + getEmojiRank(scope.userpoints) + ' emoji-align"></i>'; // this doesnt work
    },
    link: function (scope, element, attrs) {
      //console.log(getEmojiRank(scope.userpoints)); // this works
    }
  };

}]);
rex
  • 3,133
  • 6
  • 35
  • 62
  • 1
    try using template as string: '' instead of your function approach. – Luis Masuelli Mar 24 '16 at 15:27
  • Think there are typos in that it doesnt work. I would prefer to replace the entire html element if the result too (ie use replace:true) but i turned this off to see if it was the issue. – rex Mar 24 '16 at 15:34

1 Answers1

1

Well ok, a lot of issues here... First you have to define the function in the directive's scope and then call it in your template (example code, not tested):

angular.module('yourApp', []).directive('dencityRank', function(){
  return {
    restrict: 'E',
    scope: {userpoints: '='},
    controller: ['$scope', function($scope) {
      $scope.getEmojiRank = function(points){    
        // If you like you can use $scope.userpoints directly and omit the function parameter
        //...
      };
    }],
    template: '<i class= "em {{ getEmojiRank(userpoints) }} emoji-align"></i>'
  };
});


// Move somewhere into global scope to make this definition only once
Number.prototype.between = function (min, max) {
 return this >= min && this <= max;
};
Rob
  • 5,353
  • 33
  • 34