module.run() and $state.go() angularJS

All we need is an easy explanation of the problem, so here it is.

I might have some kind of missunderstanding. Im using angular ui router and i have the next issue:

I have the next State provider:

angular
.module('MainApp')
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider ) {
    $stateProvider
        .state('register', {
            url: "/",
            abstact: true,
            views: {
                "side-bar": {
                    controller: "GetSideBarCtrl"
                },
                "[email protected]": {
                    templateUrl: "/App/Views/WelcomePage.html"
                }
            },
        })
        .state('register.Register', {
            url: "Register",
            views: {
                "page-body": {
                    controller: "RegisterCtrl",
                    templateUrl: "/App/Views/Register.html"
                }
            },
        })
        .state('register.Login', {
            url: "Login",
            views: {
                "page-body": {
                    controller: "LoginCtrl",
                    templateUrl: "/App/Views/Login.html"
                }
            },
        })
        //For registered and loged in users!
    /* */
        .state('main', {
            url: "/:userId",
           // abstact: true,
            views: {
                "side-bar": {
                    controller: "GetSideBarCtrl"
                },
                "[email protected]": {
                  //  controller: "LoginCtrl",
                    templateUrl: "/App/Views/MainPage.html"
                }
            },
        });
    $urlRouterProvider.otherwise('/');
}]);

And run function

angular
.module('MainApp')
.run(['$rootScope', '$state', '$cookieStore', 'principal',
function ($rootScope, $state, $cookieStore, principal) {
    var cookies = $cookieStore.get('user');
    if (cookies) {
        principal.Authenticate(cookies.split(' ')[0], cookies.split(' ')[1]);
        $state.go('main', { userId: cookies.split(' ')[0] });
    } else {
        $state.go('register.Login');
    }
}]);

Everything works fine, when cookies are present and authenication works without any problems but $state.go does nothing, i cant figure out why, can you please help and explain me…

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Yep, as suggested it looks like $state.go() doesn’t work correctly in module.run().

I found that putting the $state code in a $timeout works, e.g.

angular.module('MainApp').run($timeout, $state, ...) {

    $timeout(function() {
        $state.go('main');
    });

}

Method 2

So i’ve made it work the different way, ive used $stateChangeStart and now my run function looks like this:

angular
.module('MainApp')
.run(['$rootScope', '$state', '$cookieStore', 'principal',
    function ($rootScope, $state, $cookieStore, principal) {
        var cookies = $cookieStore.get('user');
        if (cookies) {
            principal.Authenticate(cookies.split(' ')[0], cookies.split(' ')[1]);
        }
        $rootScope.$on('$stateChangeStart',
            function (event, toState) {
                if ((toState.name === "register") && (principal.isAuthenticated)) {
                    event.preventDefault();
                    $state.go('main', { userId: principal.identity().userId });
                }
            });
    }
]);

But i still dont know why $state.go() didnt work…

Method 3

I am having exactly the same problem.
I am using ionic to build a cross-platform mobile app.
I have logic like –> if the user is already logged in. redirect to the main page, otherwise redirect to login page

if(isLogin("userId")){
    $state.go("main");
}else{
    $state.go("login");
}

This work perfectly on Android but crash occasionally on IOS. After some investigation and research. I use $location.path instead of $state.go and everything works fine.

if(isLogin("userId")){
    $location.path("/main");
}else{
    $location.path("/login");
}

Hope this help you solve your problem.

Method 4

$state.go does not work in the run, it isn’t initialized yet so! What I did was throw the logic in a service, add a controller to the module you have the run in, run it in the controller! That should work.

Method 5

Just point that following the advises of this thread, you can also solve it changing the otherwise block for this:

  $urlRouterProvider.otherwise(function ($injector, $location) {
    var $state = $injector.get("$state");
    $state.go("/");
  });

Hope it helps

Method 6

I experienced a similar problem. $state.go not working in the .run function.

Placing $state.go in a service solved my problem.

Method 7

It can sound strange but for me the solution was to rename my state and remove the dot …

I want an home page different for customer, director, manager or anything ( but with the same url )

  .state('home', {
    url : '/',
    templateUrl: 'views/home.html',
    controller: 'HomeCtrl',
    controllerAs: 'home',
    module :'private'
  })
  .state('home.customer', {
    url : '',
    templateUrl: 'views/home-customer.html',
    controller: 'HomeCustomerCtrl',
    controllerAs: 'homeCustomer',
    module :'private'
  })

  .run(function ($rootScope, $state, $window,userService) {
    $rootScope.$on("$stateChangeStart", function(e, toState, toParams, fromState, fromParams) {
     if(toState.name === 'home') {
          if(userService.isCustomer()) {
               $state.go('home.customer');
         }
      }
}

This dosen’t work, replace the name home.customer state with home-customer and $state.go('home-customer'); and it works …

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply