Come posso risolvere “Numero massimo di stack di chiamate superato” AngularJS

Sto usando AngularJs e Ui-Router e sto provando a impostare due diverse home page, una per gli utenti che hanno effettuato l’accesso e l’altra per gli utenti che non lo sono. Ma sto ottenendo il seguente errore:

RangeError: Maximum call stack size exceeded 

Ho eseguito console.trace() e vedo che c’è un problema che causa il loop infinito degli stati (o qualcosa del genere). BUt Non ho idea di come aggiustarlo.

Ecco il codice che sta generando l’errore.

 .run(function ($rootScope, $state, $location, Auth) { $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState) { if(fromState.name === "") { if (Auth.isLoggedIn()) { $state.go('main'); event.preventDefault(); } else { $state.go('welcome'); event.preventDefault(); } } else { if (toState.authenticate && !Auth.isLoggedIn()) { $location.path('/login'); event.preventDefault(); } } }); 

Da quello che posso dire sembra derivare da if(fromState.name === "")

Ho creato un esempio , giocando con le pagine predefinite e l’utente auth / non autentico. Un problema simile potrebbe essere visto qui

In primo luogo questo sarebbe l’ascoltatore:

 app.run(function ($rootScope, $state, $location, Auth) { $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState) { var shouldLogin = toState.data !== undefined && toState.data.requireLogin && !Auth.isLoggedIn ; // NOT authenticated - wants any private stuff if(shouldLogin) { $state.go('login'); event.preventDefault(); return; } // authenticated (previously) comming not to root main if(Auth.isLoggedIn) { var shouldGoToMain = fromState.name === "" && toState.name !== "main" ; if (shouldGoToMain) { $state.go('main'); event.preventDefault(); } return; } // UNauthenticated (previously) comming not to root public var shouldGoToPublic = fromState.name === "" && toState.name !== "public" && toState.name !== "login" ; if(shouldGoToPublic) { $state.go('public');console.log('p') event.preventDefault(); } // unmanaged }); }); 

Che cosa sta succedendo?

  • Controlliamo se l’utente ha effettuato l’accesso. In caso contrario, ma richiede l’accesso a cose non pubbliche … reindirizziamo al login
  • l’utente è loggato ma non sta andando direttamente al main … lo trasferiamo
  • l’utente non ha effettuato l’accesso, ma non sta andando al pubblico … reindirizziamo
  • altrimenti … lascia che sia

E qui ci sono stati:

  $stateProvider // available for anybody .state('public',{ url : '/public', template : '
public
', }) // just for authenticated .state('main',{ url : '/main', template : '
main for authenticated
', data : {requireLogin : true }, }) // just for authenticated .state('other',{ url : '/other', template : '
other for authenticated
', data : {requireLogin : true }, }) // the log-on screen .state('login',{ url : '/login', templateUrl : 'tpl.login.html', controller : 'LoginCtrl', })

Controlla il plunker qui o qui

Usa $ state.go (“principale”, {}, {notifica: falso}); per non notificare l’evento “$ stateChangeStart”.

  // NOT authenticated - wants any private stuff if(shouldLogin) { $state.go("main", {}, {notify:false}); event.preventDefault(); return; } // authenticated (previously) comming not to root main if(Auth.isLoggedIn) { var shouldGoToMain = fromState.name === "" && toState.name !== "main" ; if (shouldGoToMain) { $state.go("main", {}, {notify:false}); event.preventDefault(); } return; }