15

I'm trying to write my first AngularJS directive: one involving the link function. The directive is being loaded, but when I use it in my page the link function is not called.


Here's the fiddle: http://jsfiddle.net/jCUSh/115/

Here's the HTML:

<div ng-app="biApp">
    <google-maps-symbol></google-maps-symbol>
</div>

and the JavaScript:

var appModule = angular.module('biApp', []);

appModule.directive('googleMapsSymbol', function () {
    console.log("Directive was run");
    return {
        link: function (scope, elem, attrs) {
            console.log("Link was called");
        }
    };
});


I'll bet I'm doing some simple thing wrong.

jcarpenter2
  • 5,312
  • 4
  • 22
  • 49

4 Answers4

21

The default for angular is to assume that directives are attributes, not elements! You are using a directive as an element so you need to specify this with the restrict. The updated code reads:

appModule.directive('googleMapsSymbol', function () {
    console.log("Directive was run");
    return {
        restrict: 'E',
        link: function (scope, elem, attrs) {
            console.log("Link was called");
        }
    };
});

Note the restrict: 'E',. Best of luck!

Updating your fiddle: http://jsfiddle.net/j8ZZ4/

idmean
  • 14,540
  • 9
  • 54
  • 83
drew_w
  • 10,320
  • 4
  • 28
  • 49
  • Thanks, that worked. The reason I was confused is that if I removed the `` element from my fiddle, the first `console.log` statement was not executed. So it looked like Angular was interpreting the element as a directive like I expected. It all makes sense now. – jcarpenter2 May 01 '14 at 17:29
5

It is not your case, but the same issue might occur when the naming of your directive is not correct. Be especially careful to dashes in the name. Since angular automagically transforms between them, it's a very very common mistake.

consider this template

<div>
  <div this-wont-work></div>
  <div this-will-work></div>
</div>

with this directives.

 angular
   .module('biApp')
   .directive('this-wont-work', () => ( { link: () => console.log('nope')} ))
   .directive('thisWillWork', () => ( { link: () => console.log('works')} ))
deddu
  • 855
  • 12
  • 16
3

I had a different problem: an ng-include in the same element was trying to include an empty string ("") and so didn't let the directive link(), for some reason.

By having a page available in the ng-include, the link() was called as expected.

Ben
  • 54,723
  • 49
  • 178
  • 224
2

Another reason this could happen for people is that there is a runtime error in one of the other compilation phases for the directive.

ng.module(MODULE).directive('myDirective', [() => {
    return {
        link() {
            // Never getting here
        },
        template() {
            // Error here would mess things up
        },
        controller() {
            // error here would mess things up
        }
    };
}]);
Kevin Beal
  • 10,500
  • 12
  • 66
  • 92