hakuna
hakuna

Reputation: 6701

AngularJS Routing not updating the menu items but loading the url and views correctly

I am doing token based authentication using MEAN stack. My application has to show Home, Signin and Signup when there is no token present i.e when a user is not logged in and Home, Me and Logout when there is a token i.e user is logged in. All my server side functionality is working fine with Signin,Signup,Logout. URL redirection in the address bar and rendering of the view is happening correctly , but the Menu items are not updating accordingly.Its getting updated only when i hit a manual refresh. Please help !

Index.html (Omitted includes):

<body ng-app="app">
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation" data-ng-controller="authCtrl">
       <!-- data-ng-controller="authCtrl" -->
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".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="#/">Angular Restful Auth</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a ng-href="#/">Home</a></li>
                    <li data-ng-show="token"><a ng-href="#/me">Me</a></li>
                    <li data-ng-hide="token"><a ng-href="#/login">Signin</a></li>
                    <li data-ng-hide="token"><a ng-href="#/register">Signup</a></li>
                    <li data-ng-show="token"><a ng-click="logout()">Logout</a></li>                    
                </ul>
            </div><!--/.nav-collapse -->
        </div>
    </div>
    <div class="container" ng-view="">
    </div> <!-- /container -->
    </body>

app.js:

'use strict';

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

var options = {};
options.api = {};
//dev URL
options.api.base_url = "http://localhost:3000";

app.config(['$locationProvider', '$routeProvider',
function($location, $routeProvider) {
  $routeProvider.
  when('/', {
    templateUrl: 'partials/home.html',
    controller: 'authCtrl'
  }).
  when('/login', {
    templateUrl: 'partials/signin.html',
    controller: 'authCtrl'
  }).
  when('/register', {
    templateUrl: 'partials/signup.html',
    controller: 'authCtrl'
  }).
  when('/me', {
    templateUrl: 'partials/me.html',
    controller: 'authCtrl'
  }).
  otherwise({
    redirectTo: '/'
  });
}]);
app.config(['$httpProvider', function ($httpProvider) {
  $httpProvider.interceptors.push('TokenInterceptor');
}]);
app.run(function($rootScope, $location, $window, AuthenticationService) {
  $rootScope.$on("$routeChangeStart", function(event, nextRoute, currentRoute) {
    //redirect only if both isAuthenticated is false and no token is set
    if (nextRoute != null && nextRoute.access != null && nextRoute.access.requiredAuthentication
      && !AuthenticationService.isAuthenticated && !$window.sessionStorage.token) {
        $location.path("/login");
      }
    });
  });

authControllers.js:

authControllers.controller('authCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function authCtrl($scope, $location, $window, UserService, AuthenticationService) {
  //Admin User Controller (login, logout)
  $scope.logIn = function logIn(username, password) {
    if (username !== undefined && password !== undefined) {
      UserService.logIn(username, password).success(function(data) {
        AuthenticationService.isLogged = true;
        $window.sessionStorage.token = data.token;
        $location.path("/me");
      }).error(function(status, data) {
        console.log(status);
        console.log(data);
      });
    }
  }
  $scope.token = $window.sessionStorage.token;
  $scope.me = function() {
    UserService.me(function(res) {      
      $scope.myDetails = res;
    }, function() {
      console.log('Failed to fetch details');
      $rootScope.error = 'Failed to fetch details';
    })
  };
  $scope.logout = function logout() {
    if (AuthenticationService.isAuthenticated) {
      UserService.logOut().success(function(data) {
        AuthenticationService.isAuthenticated = false;
        delete $window.sessionStorage.token;
        $location.path("/");
      }).error(function(status, data) {
        console.log(status);
        console.log(data);
      });
    }
    else {
      $location.path("/login");
    }
  }
  $scope.register = function register(username, password, passwordConfirm) {
    if (AuthenticationService.isAuthenticated) {
      $location.path("/me");
    }
    else {
      UserService.register(username, password, passwordConfirm).success(function(data) {
        $location.path("/login");
      }).error(function(status, data) {
        console.log(status);
        console.log(data);
      });
    }
  }
}]);

Upvotes: 0

Views: 334

Answers (2)

hakuna
hakuna

Reputation: 6701

Actually i tried a different approach that's even better to do it globally once. Injected $rootScope in my controller and assigned the SessionStorage token value.Now it works like a charm with simple change without updating $scope variable in multiple places.

authControllers.controller('authCtrl', ['$rootScope','$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function authCtrl($rootScope,$scope, $location, $window, UserService, AuthenticationService) {
$rootScope.token = $window.sessionStorage.token;
}]);

Upvotes: 0

Hamlet Hakobyan
Hamlet Hakobyan

Reputation: 33381

$scope.token = $window.sessionStorage.token;

This string doesn't bind token to storage property. You should each time update you scope variable and if you are not in digest loop then call apply explicitly.

Upvotes: 1

Related Questions