angularjs - Angular.js: page flickering on authentication redirect -
i'm implementing simple client-side authentication logic in angular.js. pages involved are:
/account#/login (public) /account (require login) /account#/settings (require login)
when user not logged in , try visit either /account
or /account/#/settings
, app supposed redirect login page.
i have following routes configured using ui-router:
$stateprovider .state('overview', { url: '/', restricted: true }) .state('settings', { url: '/settings', restricted: true }) .state('login', { url: '/login', restricted: false })
and upon url change, check if upcoming page restricted page , whether current user not logged in. if redirect login.
app.run(function($rootscope, $location, $state, auth) { $rootscope.$on('$statechangestart', function(event, next) { if (next.restricted && !auth.isloggedin()) { event.preventdefault(); $state.go('login'); } }); });
auth
service checks login status , returns either true
(logged in) or false
(not logged in).
here's question:
even though (kind of) works, see page flickering issue when trying visit restricted page while not logged in. page flashes contents of restricted page before redirecting me login page.
i did little bit researching online , people have mentioned potential solution using resolve
when defining states, since page won't load unless resolves successfully. however, when try add
resolve: { load: function(auth) { return auth.isloggedin(); } }
it didn't work. missing? using resolve
way go?
the way doing check if user logged in or not , set load
true
or false
. controller gets instantiated before load
resolved why see flickering. need achieve 2 things here:
- make sure
load
resolved before controller instantiated. - if user not logged in, redirect user login page.
for first part need use promise resolved , converted value before controller instantiated. documentation says:
if of these dependencies promises, resolved , converted value before controller instantiated , $statechangesuccess event fired.
following code can us:
var isloggedin = ['auth', '$q', function(auth, $q) { var deferred = $q.defer(); //assuming auth.isloggedin returns promise var loginpromise = auth.isloggedin(); loginpromise.then( function(response) { deferred.resolve(response); }, function(error) { deferred.reject('not logged in'); }); return deferred.promise; } ];
and states use isloggedin
:
$stateprovider .state('overview', { url: '/', resolve: { loggedin: isloggedin } }) .state('settings', { url: '/settings', resolve: { loggedin: isloggedin } }) .state('login', { url: '/login' })
for second problem, redirecting user login page, can listen $statechangeerror
event fired in case state not resolved, , use $state.go
redirect user.
Comments
Post a Comment