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
loadresolved 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