Angular directive's link function called with empty element parameter

Paul Pepper picture Paul Pepper · Apr 3, 2013 · Viewed 7k times · Source

I have a scenario where a directive's link function is called with an empty element parameter leading to errors.

A code example describes the scenario best:

index.html:

<html ng-app="app">
<body>
    <div outer></div>
</body>
</html>

Scripts:

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

app.directive('outer', function() {
    return {
        replace: true,
        controller: function($scope) {
            $scope.show = true;
        },
        templateUrl: 'partial.html'
    };
});

app.directive('inner', function($window) {
    return {
        link: function(scope, element, attrs) {
            console.log('element: ' + element);
            var top = element[0].offsetTop;
        }
    };
});

partial.html (referenced by templateUrl on outer, above):

<div ng-switch on="show">
    <div ng-switch-when="true">
       <div inner>showing it</div>
    </div>
</div>

Loading index.html in Chrome, the console reports the error: "TypeError: Cannot read property 'offsetTop' of undefined" - because element is an empty array!

Some notes:

  • replace must be set to true on directive outer.
  • templateUrl must be used by directive outer to load its partial.

I'm uncertain whether I've overlooked some configuration requirement or if this is an Angular issue. Is this a valid scenario? If it is then is it a problem with ng-switch or is there a deeper problem within Angular?

Answer

Arun P Johny picture Arun P Johny · Apr 3, 2013

Try

app.directive('inner', function($window) {
    return {
        link: function(scope, element, attrs) {
            console.log('element: ',  element);
            if(!element.length){
              console.log('Returning since there is no element');
              return;
            }
           var top = element[0].offsetTop;
           console.log('top', top)
        }
    };
});