1

I'm managing authentication with JWT. I'm trying to use ng-hide and ng-show to show/hide login and logout buttons in my nav. It's not working. The token is being stored, but I'm unable to get the show/hide to work.

Service:

angular.module('psJwtApp')
.factory('authToken', function ($window) {
  var storage = $window.localStorage;
  var cachedToken;
  var userToken = 'userToken';
  var isAuthenticated = false;

  var authToken = {
    setToken: function (token) {
      cachedToken = token;
      storage.setItem(userToken, token);
      isAuthenticated = true;
    },
    getToken: function () {
      if(!cachedToken)
        cachedToken = storage.getItem(userToken);

      return cachedToken;
    },
    isAuthenticated: function () {
      return !!authToken.getToken();
    },
    removeToken: function () {
      cachedToken = null;
      storage.removeItem(userToken);
      isAuthenticated = false;
    }
  };

  return authToken;
});

Controller:

angular.module('psJwtApp')
.controller('HeaderCtrl', function ($scope, authToken) {
  $scope.isAuthenticated = authToken.isAuthenticated();
});

html:

 <div ng-controller="HeaderCtrl" class="header">
  <ul class="nav nav-pills pull-right">
    <li ui-sref-active="active">
      <a ui-sref="main">Home</a>
    </li>
    <li ui-sref-active="active">
      <a ui-sref="jobs">Jobs</a>
    </li>
    <li ng-hide="isAuthenticated()" ui-sref-active="active">
      <a ui-sref="login">Log In</a>
    </li>
    <li ng-show="isAuthenticated()" ui-sref-active="active">
      <a ui-sref="logout">Logout</a>
    </li>
  </ul>
  <h3 class="text-muted">psJwt</h3>
</div>

1 Answers1

0

Have you checked the type of $scope.isAuthenticated? i suspect that it has resolved to a boolean, not a function. Update your html to check against the boolean value.

<li ng-show="!isAuthenticated" ui-sref-active="active">
  <a ui-sref="login">Log In</a>
</li>
<li ng-show="isAuthenticated" ui-sref-active="active">
  <a ui-sref="logout">Logout</a>
</li>
David L
  • 32,885
  • 8
  • 62
  • 93
  • When I do that, I have to refresh the browser to get it to evaluate. – xxthcenturyboy Dec 14 '14 at 21:14
  • Can you provide a small, working jsfiddle demonstrating the incorrect behavior? – David L Dec 15 '14 at 13:48
  • I got it figured out. I changed the html to "isAuthenticated()" and the controller to $scope.isAuthenticated = authToken.isAuthenticated. – xxthcenturyboy Dec 17 '14 at 05:20
  • Just for clarification, I think this was because the isAuthenticated method was not being evaluated on reload, but since your controller now passes in the actual method, it gets evaluated when Angular parses the template. I'm curious if this is better than using $broadcast in your Auth service. This has to check for the token a lot. – steezeburger Mar 26 '16 at 21:55
  • 1
    @steezeburger I think it depends on your perspective. Internally registered watchers (core angular directives) are relatively cheap, particularly in something like this that checks a simple boolean property. In addition, once the property state stops changing, it won't need to be continuously reevaluated. Personally, I've made considerable concerted efforts to minimize broadcasting and emitting as much as possible. I now favor heavily componetized directive/component driven approaches that push values down the stack and minimize events as much as possible. – David L Mar 27 '16 at 00:36
  • 1
    @DavidL Ahh, that makes sense. Thanks for answering my curiosity! – steezeburger Mar 27 '16 at 05:52