Arthur
Arthur

Reputation: 2110

AngularJS : Directive not picking up attribute

I have got the following directive:

app.directive('ngAvatar', function() {
  return {
    restrict: 'E',
    replace: true,
    template: '<img class="avatar-medium" ng-src="{{url}}" />',
    link: function(scope, elem, attrs) {
      console.log(attrs);
      var aType = attrs.avatarType;
      var aId = attrs.avatarId;
      console.log("Type: "+ aType);
      console.log("Character ID:"+ aId);
      var baseUrl = "http://api-character.com/";
      switch(aType){
        case "character":
          scope.url = baseUrl + "Character/"+aId+"_256.jpg";
      }
    }
  }
});

Unfortunately the directive is not picking up the avatar_id inside of the directive. As you can see I am console logging the attributes:

console.log("Type: "+ aType);
console.log("Character ID:"+ aId);

In my view I am using this directive like so:

<ng-avatar avatar_type="character" avatar_id="{{character.character_id}}"></ng-avatar>

The following is the output of my console in Chrome. As you can see the avatar_id is showing as blank but on inspection of the attrs you can see that the attribute is there but just not showing in the directive code.

Chrome Console:

enter image description here

Does anyone have any idea why it would not work?

Thanks

Upvotes: 1

Views: 528

Answers (1)

PSL
PSL

Reputation: 123739

There could be many ways to solve this problem.

using one time watch - you could also consider using two-way bound isolated scoped directive

   link: function(scope, elem, attrs) { 
      //Set up watch
      var unWatch = scope.$watch(attrs.avatarId, function(v){
        if(v){
          unWatch();
          init();
        }
      });
     function init(){
       //initialize here
     }
   }

and bind it as:

   <ng-avatar avatar-type="character" avatar-id="character.character_id"></ng-avatar>

Use attribute observe

  link: function(scope, elem, attrs) { 
      //Set up watch
      var unWatch = attrs.$observe(attrs.avatarId, function(v){
        if(v){
          unWatch();
          init();
        }
      });
     function init(){
       //initialize here
     }
  }

and use it with

 <ng-avatar avatar-type="character" avatar-id="{{character.character_id}}"></ng-avatar>

Bind promise/data

  app.directive('ngAvatar', function($q) {
   //...
   link: function(scope, elem, attrs) { 
      //Set up watch
     $q.when(scope.$eval(attrs.character)).then(init); 

     function init(character){
       var id = character.id;
       //initialize here
     }
    }
  } 

and bind it as

 <ng-avatar avatar-type="character" avatar-id="characterPromiseOrCharObject"></ng-avatar>

Event bus

Just use angular event bus and broadcast an event from the controller which sets the data say char_loaded, listen for the event in the directive using scope.$on and once you get it initialize.

Upvotes: 1

Related Questions