9

Basically, I want to measure the width of the element after angular has manipulated the DOM. So I would like to use $timeout for that, but it keeps getting me errors.

HTML

   <div ng-app="github">
      <ul mynav>
        <li ng-repeat="nav in navItems">{{nav.name}}</li>
      </ul>

      </div>
    </div>

CSS

ul,li {
  display:inline-block;
}
li {
  margin-right:1em;
}

JS

(function() {
  angular.module('github', [])
    .directive('mynav', function($window) {
      return {
        restrict: 'A',
        link: function(scope, element, attrs, timeout) {
          scope.navItems = [{
            "name": "home"
          }, {
            "name": "link1"
          }, {
            "name": "link2"
          }, {
            "name": "link3"
          }];
          timeout(function() {
            console.log($(element).width());
          })
        }

      }
    });
})();
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Artvader
  • 906
  • 2
  • 15
  • 31

3 Answers3

15

link function isn't a correct place to inject dependency. It has defined sequence of parameter like I shown below. You can't put dependency there.

link(scope, element, attrs, controller, transcludeFn) {

Inject $timeout dependency in directive function.

(function() {
  angular.module('github', [])
    .directive('mynav', function($window, $timeout) { //<-- dependency injected here
      return {

Then just use injected $timeout inside link function

$timeout(function() {
    console.log(element.width());
})
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
-1
setInterval(function(){
    // code here
    $scope.$apply();
}, 1000); 

$apply is included as a reminder that since this is an external jQuery call you need to tell angular to update the DOM.

$timeout being an angular version automatically updates the DOM

  • 1
    Don't encourage to use `$apply`, its bad pattern to use, Though `$timeout` does help to update **bindings** not **DOM** – Pankaj Parkar Aug 26 '16 at 13:04
-2

Just replace timeout with setinterval like below:

(function() {
  angular.module('github', [])
    .directive('mynav', function($window) {
      return {
        restrict: 'A',
        link: function(scope, element, attrs, timeout) {
          scope.navItems = [{
            "name": "home"
          }, {
            "name": "link1"
          }, {
            "name": "link2"
          }, {
            "name": "link3"
          }];
          setInterval(function() { // replpace 'timeout' with 'setInterval'
            console.log($(element).width());
          })
        }

      }
    });
})();

Hope it works for you.

Kunal Kakkad
  • 653
  • 6
  • 19
  • 1
    bad idea, you should use angular dependencies, otherwise you will be need to call `$apply` method to update scope. – grinry Aug 26 '16 at 11:33