0

My problem is similar to this : ng-show and ng-hide with jwt

Although i modified as instructed by user3735441, i still can't make them work properly:

Service :

'use strict';

/**
 * @ngdoc service
 * @name ToDoManagerApp.authToken
 * @description
 * # authToken
 * Factory in the ToDoManagerApp.
 */
angular.module('ToDoManagerApp').factory('authToken', function($window) {
    var storage = $window.localStorage;
    var cachedToken;
    var userToken = 'userToken';
    var isAuthenticated = false;
    // Public API here
    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('ToDoManagerApp').controller('HeaderCtrl', function($scope, authToken) {
    $scope.isAuthenticated = authToken.isAuthenticated;

});

HTML :

<div ng-controller = "HeaderCtrl" class="header">
  <div class="navbar navbar-default" role="navigation">
    <div class="container">
      <div class="navbar-header">

        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#js-navbar-collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>

        <a class="navbar-brand" href="#/">ToDoManager</a>
      </div>

      <div class="collapse navbar-collapse" id="js-navbar-collapse">

        <ul class="nav navbar-nav">
          <li ui-sref-active="active">
            <a ui-sref="main">Home</a>
          </li>
          <li ng-hide="isAuthenticated()" ui-sref-active="active">
            <a ui-sref="register">Register</a>
          </li>
          <li ng-show="isAuthenticated()" ui-sref-active="active">
            <a ui-sref="logout">Logout</a>
          </li>
        </ul>
      </div>
    </div>
  </div>
</div>

What i'm trying to do is to :

1 - show register, hide logout when no token is set (not authenticated) OR 2 - show logout, hide register when a token is set (authenticated)

For now i'm stuck with the first state, authenticated or not i can't see the logout button.

Community
  • 1
  • 1
redAce
  • 1,558
  • 4
  • 14
  • 24

3 Answers3

0

You are accessing the $scope model with ng-hide and ng-show. In your Service, you are setting isAuthenticated to false, and never setting it to True. So your app is stuck in your first state, where the isAuthenticated is false.

Tui Popenoe
  • 2,098
  • 2
  • 23
  • 44
  • I did set it to true in setToken : setToken: function(token) { cachedToken = token; storage.setItem(userToken, token); isAuthenticated = true; }, – redAce Feb 20 '15 at 20:44
  • Where are you calling the setToken? – Tui Popenoe Feb 20 '15 at 20:44
  • I do it in the register controller : $http.post(url, user).success(function() { alert('success', 'OK!', 'You are now registered'); authToken.setToken(res.token); }) – redAce Feb 20 '15 at 20:51
  • Put a watch on this isAuthenticated variable, I think you will find it is not being changed. – Tui Popenoe Feb 20 '15 at 20:54
0

I completly forgot to add 'res' in my register controller, that's why it wasn't updated :

$http.post(url, user)
            .success(function(res) {
                alert('success', 'OK!', 'You are now registered');
                authToken.setToken(res.token);
            })
redAce
  • 1,558
  • 4
  • 14
  • 24
0

This is happening because your variable in your controller is not updating when it changes in your factory. To work around this, I usually use $broadcast. So in your factory you would have some function like this...

var broadcastValue = function() {
  $rootScope.$broadcast('IsAuthenticated');
}

You would then call this function at whatever point you wanted the receivers to check the variable.

Then in your controller you would have something like this to receive the broadcast

$scope.$on('IsAuthenticated', function() {
  $scope.isAuthenticated = authToken.isAuthenticated;
});

This will make sure your controller sees when the value changes.

Also see this post.

$on and $broadcast in angular

Community
  • 1
  • 1
ribsies
  • 1,218
  • 2
  • 10
  • 16