0

I am using UI-Router and trying to access my web app's current state from within a directive, using the following:

footer.directive.js

(function () {
  'use strict';

  angular
    .module('app')
    .directive('myFooter', myFooter);

  myFooter.$inject = ['$cookies', 'userFactory', '$state', '$log', '$rootScope'];

  function myFooter($cookies, userFactory, $state, $log, $rootScope) {
    var directive = {
      restrict: 'E',
      templateUrl: 'app/components/footer/footer.html',
      controller: FooterController,
      controllerAs: 'vm',
      bindToController: true
    };

    return directive;

    function FooterController($state) {
      var vm = this;

      vm.currentState = $state;
    }
  }

})();

footer.html

<div class="footer">
  <p>{{ vm.currentState.current.name }}</p>
</div>

When I run $log.log($state) it posts an object in my console that has a current object with a name attribute that is equal to the state name that I need, but when I try to reference the $state.current.name, either on my view or by logging it to the console, it displays as an empty string.

I'm a bit new to Angular, so if someone could explain to me what is going on here or at the least how to fix this so that I can display what I want properly, that would be a huge help. Thanks!

Edit: Two other questions that I looked at before posting this one are:

This one which seems to deal more with changing a class name based on state name, and this one, which doesn't quite address my problem either (and doesn't look like it could possibly be the right way to do this.)

Community
  • 1
  • 1
turner
  • 1,667
  • 2
  • 13
  • 21

2 Answers2

0

First of all, there is a naming bug in your posted code! (amaiFooter)

The second thing is, if you log an object, it's bound by a call by reference

So the moment you log it, you log the reference. That means when you look at it, it can contain other values than when you have logged it

But when you logged the state name and it was undefined, that was the right output!

You can try to wrap it in a $timeout function with 0 delay, just to add your code to the end of the current digest cycle, that should solve your problem

Anditthas
  • 531
  • 1
  • 3
  • 11
  • Sorry, the naming error was a result of paring it down to an MVP, I just fixed it. Also, isn't the 'vm.currentState' also a reference to that object? So when I do vm.currentState.current.name on the partial, why doesn't that show up correctly? – turner Dec 08 '15 at 21:34
  • And I suppose a more important question is, why does this work normally and without problems in my controllers elsewhere, but this directive controller doesn't work like these do? – turner Dec 08 '15 at 21:57
0

You need inject the state service on the controller as follows

(function () {
  'use strict';

  angular
    .module('app')
    .directive('myFooter', myFooter);

  myFooter.$inject = ['$cookies', 'userFactory', '$state', '$log', '$rootScope'];

  function myFooter($cookies, userFactory, $state, $log, $rootScope) {
    var directive = {
       restrict: 'E',
       templateUrl: 'app/components/footer/footer.html',
       controller: FooterController,
       controllerAs: 'vm',
       bindToController: true
    };

    return directive;
  }

  FooterController.$inject = ['$state'];
  function FooterController($state) {
    var vm = this;

    vm.currentState = $state;
  }

})();