最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I fix 'Maximum call stack size exceeded' AngularJS - Stack Overflow

programmeradmin3浏览0评论

I am using AngularJs and Ui-Router and I am trying to set two different home pages, one for users that are logged in and the other for users that aren't. But I am getting the following error:

RangeError: Maximum call stack size exceeded

I ran console.trace() and I can see that there is an issue which is causing the states to loop infinitely (or something like that). BUt I have no idea how to fix it.

Here is the code that is generating the error.

.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();
         }
      }
    });

From what I can tell it seems to stem from if(fromState.name === "")

I am using AngularJs and Ui-Router and I am trying to set two different home pages, one for users that are logged in and the other for users that aren't. But I am getting the following error:

RangeError: Maximum call stack size exceeded

I ran console.trace() and I can see that there is an issue which is causing the states to loop infinitely (or something like that). BUt I have no idea how to fix it.

Here is the code that is generating the error.

.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();
         }
      }
    });

From what I can tell it seems to stem from if(fromState.name === "")

Share Improve this question asked Jul 30, 2014 at 4:05 DaimzDaimz 3,28114 gold badges51 silver badges77 bronze badges 4
  • where's your loop. When a loop runs for infinitive this error occurs – Mritunjay Commented Jul 30, 2014 at 4:06
  • Sorry I didn't mean I have a 'loop' I meant more the error is looping or the state.go perhaps is looping. I have updated the question, hopefully it's a bit more clear. – Daimz Commented Jul 30, 2014 at 4:09
  • Make sure you aren't changing $rootScope variables inside $state.go, that could be the cause, though normally that causes an infinite $digest error. It's an odd error, best would be to try replicate it in a plunkr, normally I find the process of trying to replicate it outside of my environment helps figure out the problem. Also working examples are clearer for weird problems! – Simeon Cheeseman Commented Jul 30, 2014 at 4:49
  • I don't actually know how I can set it up on plunkr to replicate, I am using angular-fullstack and which includes express and mongo I can't get the auth to work with out the rest of the app. So I can't make a fair example that will throw the error. – Daimz Commented Jul 30, 2014 at 4:56
Add a comment  | 

2 Answers 2

Reset to default 10

I've created an example, playing with default pages and auth/unauth user. Similar issue could be seen here

Firstly this would be the listener:

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
    });
});

What is happening?

  • We check if user is logged in. If not, but requires access to not public stuff... we redirect to login
  • user is logged in but not going directly to main... we transfer him
  • user is not logged in, but not going to public ... we redirect
  • else... let it be

And here are states:

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

Check plunker here or here

Use $state.go("main", {}, {notify:false}); for not notify to "$stateChangeStart"event.

  // 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;
  }
发布评论

评论列表(0)

  1. 暂无评论