Osama Yawar Osama Yawar - 7 months ago 29
Javascript Question

How to avoid AngularJS page flick

I am new to AngularJS and created my first one page application. I create various routes that includes one for homepage(/) and other for Login(/login).

When my app module runs it first initialize $rootScope.authentication = false; and validate if the user is logged in, if not, then the user is redirected to /login page otherwise home page.

var myApp = angular.module('myApp', ['ngRoute']);
myApp.run(function($rootScope, $http, $location, $routeParams){
$rootScope.authenticated = false;
$rootScope.$on("$routeChangeStart", function(e, current, previous){
$http.get('api/user/authenticated')
.then(function(res){
if(res.data.authenticated == true && angular.isDefined(res.data.authenticated)) {
$rootScope.authenticated = res.data.authenticated;
$rootScope.clinicname = res.data.clinic_name;
$rootScope.email = res.data.email;

if(angular.isDefined(previous)) {
if (angular.isObject(current.$$route) && angular.isObject(previous.$$route)) {
if (current.$$route.originalPath === '/login') {
$location.path(previous.$$route.originalPath);
}
}
}
}
else {
$rootScope.authenticated = false;
if (angular.isObject(current.$$route)) {
if (current.$$route.originalPath !== '/login') {
$location.path('/login');
}
}
}
});
});
console.log($rootScope);
});


index.html

<body class="hold-transition skin-blue sidebar-mini">
<div ng-if="authenticated == false">
<section class="content-header">
<div ng-view></div>
</section>
</div>

<div ng-if="authenticated" class="wrapper">
<!-- Content here !-->
<div class="content-wrapper">
<section class="content-header">
<div ng-view></div>
</section>
</div>
</div>


Now the problem is that when the user is not logged in, it first displays a glimpse of the homepage and quickly jump on the login page.

I want to somehow deal with this flick. What wrong am i doing?

Answer

What you want is to execute your authentication logic in the onEnter callback on your route.

This event will resolve in full before continuing execution, meaning that if the authentication (or any other logic you need to execute) fails, the user can be redirected and will never see the route they were trying to access.

.state("homepage", {
              url: "/",
              controller: 'homepageController',
              templateUrl: "/homepage.html",
              onEnter: ['$state', 'authService', function ($state, authService) {
                  if (!authService.hasPermission(this.name)) {
                      $state.go('login');
                  }
              }]
          })

In this example, I'm using an service to check if the user is authorized to access this route, but you can execute any logic you need to here.

Comments