I'm developing a small application with angular and I'm having a hard time solving the template flicker (shows one template then immediately shows another one) problem I'm facing.
I have an <ng-view>
tag defined in my base template and a few partial files.
This is my routeProvider
setting:
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: '/static/partials/login.html',
controller: 'LoginController',
requireLogin: false
}).
when('/login', {
templateUrl: '/static/partials/login.html',
controller: 'LoginController',
requireLogin: false
}).
when('/register', {
templateUrl: '/static/partials/register.html',
controller: 'RegisterController',
requireLogin: false
}).
when('/profile', {
templateUrl: '/static/partials/profile.html',
controller: 'ProfileController',
requireLogin: true
}).
otherwise({
redirectTo: '/'
});
}]);
As you can see, I'm defining a requireLogin property to check if the corresponding route requires the user to be logged into the webapp.
The following is an interceptor I defined that checks if the requireLogin property is set and if it is, it asks the server if the user is authenticated. If the user is not authenticated it redirects him to the login page.
app.run(function($rootScope, $location, $http) {
$rootScope.$on('$routeChangeStart' , function(event, current) {
if(current.requireLogin) {
$http.get('/authenticated').success(function(response){
if(!response.authenticated) {
$location.path('/');
}
});
}
});
});
The flicker happens when the user is not authenticated.
I'm developing a small application with angular and I'm having a hard time solving the template flicker (shows one template then immediately shows another one) problem I'm facing.
I have an <ng-view>
tag defined in my base template and a few partial files.
This is my routeProvider
setting:
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: '/static/partials/login.html',
controller: 'LoginController',
requireLogin: false
}).
when('/login', {
templateUrl: '/static/partials/login.html',
controller: 'LoginController',
requireLogin: false
}).
when('/register', {
templateUrl: '/static/partials/register.html',
controller: 'RegisterController',
requireLogin: false
}).
when('/profile', {
templateUrl: '/static/partials/profile.html',
controller: 'ProfileController',
requireLogin: true
}).
otherwise({
redirectTo: '/'
});
}]);
As you can see, I'm defining a requireLogin property to check if the corresponding route requires the user to be logged into the webapp.
The following is an interceptor I defined that checks if the requireLogin property is set and if it is, it asks the server if the user is authenticated. If the user is not authenticated it redirects him to the login page.
app.run(function($rootScope, $location, $http) {
$rootScope.$on('$routeChangeStart' , function(event, current) {
if(current.requireLogin) {
$http.get('/authenticated').success(function(response){
if(!response.authenticated) {
$location.path('/');
}
});
}
});
});
The flicker happens when the user is not authenticated.
Share Improve this question asked Jun 17, 2014 at 12:50 georgezgeorgez 7351 gold badge9 silver badges20 bronze badges3 Answers
Reset to default 8$routeProvider supports a 'resolve' property, which addresses the flicker by delaying the route change until all promises from the resolve object have been resolved. The resolve properties are injectable into your controller function. Here is an example of how it works:
when('/profile', {
templateUrl: '/static/partials/profile.html',
controller: function($scope, profile, loginInfo) {
$scope.data = profile.data;
$scope.loginInfo = loginInfo;
},
requireLogin: true,
resolve: {
profile: function($http) {
// return a promise
return $http({ method: 'GET', url:'/getProfile' });
},
loginInfo: function() {
// return an object literal
return { details: { ... } }
},
etc
}
}).
Look into ngClock. This could be a solution. https://docs.angularjs/api/ng/directive/ngCloak .It states that
"The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (unpiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display".
As answered before: you can use ng-cloak.
but i think it would not solve your problem, because the request happens afterwards.
maybe you can use a modal to ask for the credentials of the user. i do something similar and it works perfekt. (the modal shows with fade in if the user isn't authorized)
in your $routeChangeStart event you can check if authorization is needed. if not, send a loginRequired broadcast.
$rootScope.$on('$stateChangeStart', function (event, nextState) {
if (nextState.requireLogin) {
event.preventDefault();
$rootScope.$broadcast('auth-change', 'loginRequired', nextState.name);
}
});
a logincontroller handles the loginRequired event and displays the modal.