ui-router - $state.go() not working


Here is the app.js of my project:

(function () {
'use strict';

    .module('app', ['ui.router', 'ngCookies', 'angular-inview', 'ngMaterial'])

config.$inject = ['$stateProvider', '$urlRouterProvider', '$mdThemingProvider'];
function config($stateProvider, $urlRouterProvider, $mdThemingProvider) {
            .accentPalette('teal', {
              'default': 'A400'


            .state('app', {
                url: '/app',
                data: {
                    clearenceLevel: 1
                  views: {
                    '': {
                        templateUrl: 'app/views/navbar.html',
            .state('home.works', {
                url: '/works',
                templateUrl: 'app/views/works.html',
                controller: 'WorksController as vm'
            .state('login', {
                url: '/login',
                templateUrl: 'app/views/login.html',
                controller: 'LoginController as vm',
                data: {
                    clearenceLevel: 0
            .state('register', {
                url: '/register',
                templateUrl: 'app/views/register.html',
                controller: 'RegisterController as vm',
                data: {
                    clearenceLevel: 0
run.$inject = ['$rootScope', '$location', '$state', '$cookieStore', '$http', 'AuthenticationService'];
function run($rootScope, $location, $state, $cookieStore, $http, AuthenticationService) {
    $rootScope.globals = $cookieStore.get('globals') || {};

    if ($rootScope.globals.currentUser) {
        $http.defaults.headers.common['aimm-token'] = $rootScope.globals.currentUser.token;
        $http.defaults.headers.common['aimm-id'] = $rootScope.globals.currentUser.id;

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
        var clearenceLevel = toState.data.clearenceLevel;
        var loggedIn = $rootScope.globals.currentUser;

        if (clearenceLevel > 0 && !loggedIn) {
            return $state.go('login');

I just can't have $state.go() working. The $on('$stateChangeStart'...); is working fine, and the alert is poping when trying to reach a protected state with no session. But the return $state.go('login'); doesnt work. It redirects to /app.

Thanks for your help.

Problem courtesy of: Ruben Renzema


Well, thanks to @Vanojx1, I found out adding e.preventDefault(); before the $state.go('login'); made it work. Still dont understand why though.

Solution courtesy of: Ruben Renzema


You need to execute the $state.go on main scope and not in a (angular) service or virtual scope created temporarily.

You can also solve the problem by wrapping it in $timeout or setTimeout which will register it in the browser loop to be executed after the current method run etc even with 0 milliseconds will do it, like.



Discussion courtesy of: ahmadalibaloch

This recipe can be found in it's original form on Stack Over Flow.