javascript - AngularJS ui router $stateChangeStart with promise inifinite loop -


i'm trying build sort of authentication in angular app , redirect external url when user not logged in (based on $http.get).

somehow end in infinite loop when event.preventdefault() first line in $statechangestart.

i've seen multiple issues answers on stackoverflow, saying "place event.preventdefault() before state.go in else". controllers fired , page shown before promise returned.

even when put event.preventdefault() in else, odd happens:

going root url, automatically adds /#/ after url , $statechangestart fired multiple times.

app.js run part:

.run(['$rootscope', '$window', '$state', 'authentication', function ($rootscope, $window, $state, authentication) {     $rootscope.$on('$statechangestart', function (event, tostate, toparams) {         event.preventdefault();         authentication.identity()         .then(function (identity) {              if (!authentication.isauthenticated()) {                  $window.location.href = 'external url';                  return;             } else {                  $state.go(tostate, toparams);             }         });     }); }]); 

authentication.factory.js identity() function:

function getidentity() {     if (_identity) {         _authenticated = true;         deferred.resolve(_identity);         return deferred.promise;     }      return $http.get('url')     .then(function (identity) {          _authenticated = true;         _identity = identity;         return _identity;     }, function () {         _authenticated = false;     }); } 

edit: added states:

$stateprovider     .state('site', {         url: '',         abstract: true,         views: {             'feeds': {                 templateurl: 'partials/feeds.html',                 controller: 'userfeedscontroller userfeedsctrl'             }         },         resolve: ['$window', 'authentication', function ($window, authentication) {             authentication.identity()             .then(function (identity) {                 if (!authentication.isauthenticated()) {                     $window.location.href = 'external url';                 }             })         }]     })     .state('site.start', {         url: '/',         views: {             'container@': {                 templateurl: 'partials/start.html'             }         }     })     .state('site.itemlist', {         url: '/feed/{feedid}',         views: {             'container@': {                 templateurl: 'partials/item-list.html',                 controller: 'itemlistcontroller itemlistctrl'             }         }     })     .state('site.itemdetails', {         url: '/items/{itemid}',         views: {             'container@': {                 templateurl: 'partials/item-details.html',                 controller: 'itemscontroller itemsctrl'             }         }     }) }]) 

if need more info, or more pieces of code app.js let me know !

$statechangestart not wait promise resolved before exiting. way make state wait promise use resolve within state's options.

.config(function($stateprovider) {   $stateprovider.state('home', {     url: '/',     resolve: {       auth: function($window, authentication) {         return authentication.identity().then(function (identity) {            if (!authentication.isauthenticated()) {              $window.location.href = 'external url';            }         });       }     }   }); }); 

by returning promise function, ui-router won't initialize state until promise resolved.

if have other or children states need wait this, you'll need inject auth in.

from wiki:

the resolve keys must injected child states if want wait promises resolved before instantiating children.


Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -