Search code examples
angularjsangular-ui-routerhistoryback-button

angular ui-router on back press TypeError: a.indexOf is not a function


I'm working on an Angular 1.6.1 web-application with Angular Material and ui-router modules installed.

Navigating from state to state is working fine but when the browser back button is pressed the URL is changing but the state is not (the view stays the same)! I get the following error in the console log:

TypeError: a.indexOf is not a function
at f (angular.js:438)
at m (angular.js:438)
at Object.z.transitionTo (angular.js:438)
at Array.<anonymous> (angular.js:438)
at Object.invoke (angular.js:39)
at g (angular.js:438)
at angular.js:438
at b (angular.js:438)
at n (angular.js:438)
at m.$broadcast (angular.js:146)

The $stateChangeStart is not even reached.

So it seems like there is something happening to the browser history stack.

A couple of days ago everything worked fine, did not change anything since then (well, not according to my git log).

My $stateProvider config is divided over different files, the first file looks likes this:

  $stateProvider
        //Main states
        .state('main', {
            abstract: true,
            controller: 'MainController',
            template: '<div ui-view flex layout="column"></div>'
        })
        .state('null', {
            parent: 'main',
            url: '/',
            controller: function($state){
                $state.go('login', {}, {location: "replace", reload: true});
            }
        })
        //main loggedin state loading main loggedin view
        .state('logged-in', {
            parent: 'main',
            abstract: true,
            templateUrl: COMP_DIR + 'core/logged-in/logged-in.view.html',
            controller: 'LoggedInController',
            controllerAs: 'vm'
        })

        .state('no-enterprise', {
            parent: 'logged-in',
            abstract: true,
            template: '<div ui-view flex layout="column"></div>',
            controller: 'NoEnterpriseController'
        })

After this configuration I include a couple of routing files for each module of the application. After that I add the last routing file like this:

 $stateProvider
    //main enterprise state
        .state('enterprise', {
            parent: 'logged-in',
            url: '/{slug}',
            controller: 'EnterpriseController',
            controllerAs: 'vm',
            template: '<div ui-view flex layout="column"></div>'
        })

        //states inside enterprise state
        .state('dashboard', {
            url: '/',
            parent: 'enterprise',
            title: 'Dashboard',
            templateUrl: COMP_DIR + 'dashboard/dashboard.index.view.html',
            controller: 'Dashboard.DashboardController',
            controllerAs: 'vm'
        })

The state changes are being triggered by adding a simple ui-sref to an element and that is working fine, but i'm not able to go back with the back button of the browser.

Does anybody have an idea why this error is popping up and the back button is therefore not working properly?

Thanks in advance!

Edit: Additionally, when I refresh the application (pressing F5) back button is working until I navigate forward one step, then I get the same error trying to navigate forward in the history stack.


Solution

  • I solved the problem. There was an error in the $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams) {} function.

    I tried to compare the toState.name to something undefined.

    Which was weird because the error occurs before the state change. So if you have a error while changing states be sure to check your $stateChangeSuccess event handler ;)