Search code examples
javascriptangularjsangularjs-routing

Why angular redirects to the route but loads the wrong view


I have a basic need I wanted to address with routes:

  1. A bunch of routes defined
  2. If the user is not authenticated, then he's redirected to the login page

My problem is that, the first time the web app is displayed, the user seem to be correctly redirected because the URI is correct, but not the displayed view (it corresponds to the default view).

I've created a jsbin for that, if you prefer to see it for real. The result can be viewed here.

Steps to reproduce:

  1. Load the page
  2. You see needsAuth, meaning that the content of the view needsAuth is displayed even if the URI contains login (which corresponds to the view login)
  3. Reload the page
  4. You see 'login', meaning that the content of the view login

The HTML code:

<!DOCTYPE html>
<html ng-app='app'>
<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular-route.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div ng-view>
  </div>
</body>
</html>

Here is the javascript code:

var template = '{{vm.text}}';

angular
  .module('app', ['ngRoute'])
  .config(['$routeProvider', routes])
  .controller('needsAuthController', needsAuthController)
  .controller('loginController', loginController)
  .run(['$rootScope', '$location', registerRedirection]);

function routes($routeProvider){
  $routeProvider
    .when('/needsAuth', {
      controller: 'needsAuthController',
      controllerAs: 'vm',
      template: template
    })
    .when('/login', {
      controller: 'loginController',
      controllerAs: 'vm',
      template: template
    })
    .otherwise({
      redirectTo: '/needsAuth'
    });
}

function needsAuthController(){
  var vm = this;

  vm.text = 'needsAuth';
}

function loginController(){
  var vm = this;

  vm.text = 'login';
}

function registerRedirection($rootScope, $location){
  $rootScope.$on('$routeChangeStart', function(event, next){
    $location.path('/login');
  });
}

On the first load, you can see that URI and content do not match Result on first load

If I reload the page, everything is working as expected: Result after reloading the page

Is there something I'm doing wrong? If it's the case, what is the correct way to redirect user under some conditions?

[Edit]: Angular 1.2.26 seems to behave correctly in this case, but not angular 1.3.2


Solution

  • Change

    function registerRedirection($rootScope, $location){
       $rootScope.$on('$routeChangeStart', function(event, next){
           $location.path('/login');
       });
    }
    

    To

    function registerRedirection($rootScope, $location){
       $rootScope.$on('$locationChangeStart', function(event, next){     
    
                         ^ change this ^    
    
           $location.path('/login');
       });
    }
    

    And then your initial load works correctly.