angular-ui / ui-router

The de-facto solution to flexible routing with nested views in AngularJS
http://ui-router.github.io/
MIT License
13.54k stars 3k forks source link

Cannot read property '@' of null when using $state in onEnter #1434

Closed johannesjo closed 9 years ago

johannesjo commented 9 years ago

When using the following setup

           //Dashboard routes
            .state('dashboard', {
                abstract: true,
                url: '/dashboard',
                templateUrl: 'modules/dashboard/_layout.html'
            })
            .state('dashboard.overview', {
                url: '/cases',
                templateUrl: 'modules/dashboard/issue/issues.html',
                controller: 'IssuesCtrl',
                resolve: {
                    issues: function (Issues, $state)
                    {
                        console.log($state);

                        return Issues.query().$promise;
                    }
                },
                onEnter: function (issues, $state)
                {
                    console.log(issues, $state);

                    if (issues.length === 1) {
                        $state.go('dashboard.issue', {id: issues[0].id})
                    }
                }
            })

I get the following 2 errors

TypeError: Cannot read property '@' of null
    at updateView (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3268:82)
    at http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3239:11
    at Scope.$get.Scope.$broadcast (http://localhost:9000/bower_components/angular/angular.js:13790:50)
    at Object.load (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:2999:22)
    at Object.injectables.$template (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:2899:24)
    at Object.invoke (http://localhost:9000/bower_components/angular/angular.js:4260:27)
    at proceed (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:411:42)
    at invoke (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:407:26)
    at study (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:386:14)
    at $Resolve.resolve (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:490:34) angular.js:10629
TypeError: Cannot read property '@dashboard' of null
    at updateView (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3268:82)
    at http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:3239:11
    at Scope.$get.Scope.$broadcast (http://localhost:9000/bower_components/angular/angular.js:13790:50)
    at Object.load (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:2999:22)
    at Object.injectables.$template (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:2899:24)
    at Object.invoke (http://localhost:9000/bower_components/angular/angular.js:4260:27)
    at proceed (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:411:42)
    at invoke (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:407:26)
    at study (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:386:14)
    at $Resolve.resolve (http://localhost:9000/bower_components/angular-ui-router/release/angular-ui-router.js:490:34) angular.js:10629

when trying to enter the route with issue.length being 1.

When I use return Issues.query() instead of return Issues.query().$promise the issues are not resolved inside onEnter.

johannesjo commented 9 years ago

Plunkr might not be 100% the same, but if you try to go back to the index route the same error occurs: http://plnkr.co/edit/fDEQPz0clf37yqnsa59C?p=preview

christopherthielen commented 9 years ago

Thanks. I'm fairly certain this is a dupe of #1234. This should be fixed in the next major release.

christopherthielen commented 9 years ago

@johannesjo I'm closing due to duplicate. Please follow #1234 or reopen if you believe they are not the same bug.

yaru22 commented 9 years ago

I encountered the same bug as in this issue. When I tried to go to the same state but with different query parameter using $state.go(<sameStateName>, { queryParam1: someQueryParam }), I get the exact same error messages. @christopherthielen When do you think the next major release be ready?

christopherthielen commented 9 years ago

@yaru22 you went to the current state with a different query param and you get this? I think that's a different corner case than the original poster.

Can you verify that is indeed what is happening? If so, can you provide a simple plunk? http://bit.ly/UIR-Plunk

A Preview build of the next major release is about 3 weeks away, hopefully.

jzelez commented 9 years ago

I've hit the same issue as @yaru22, and have created a simple plunk to demonstrate: http://plnkr.co/edit/3oJE9X7DV40tfs7QLuGX?p=preview

The error(s) are thrown when going from product_list to product_detail states.

benbuckman commented 9 years ago

I had a similar issue. The workaround with an intermediary redirect didn't work for me. Wrapping $state.go() in a $timeout solved it for me (via https://stackoverflow.com/a/24977366). Maybe helpful to others landing here...

heston commented 9 years ago

I just ran into this issue as well. As for @benbuckman, using an intermediate state did not resolve the issue for me. Using a $timeout does work, but it results in a noticeable "break" between states where there is nothing rendered in the view (since, effectively, this approach loads the state in two digest cycles instead of one).

erichjsonfosse commented 9 years ago

I'm having the same problem, and it's not the same as #1234, as I'm only trying to redirect once.

.state('venues', {
            url: '/venues',
            templateUrl: 'views/venues/venues.html',
            controller: 'VenuesCtrl',
            onEnter: function ($state, $window) {
                if (!$window.localStorage.getItem('selectedVenue')) {
                    $window.localStorage.removeItem('selectedExhibition');
                } else if (!$window.localStorage.getItem('selectedExhibition')) {
                    $state.go('venue', {id: $window.localStorage.getItem('selectedVenue')});
                } else {
                    $state.go('exhibition', {venueId: $window.localStorage.getItem('selectedVenue'), id: $window.localStorage.getItem('selectedExhibition')});
                }
            }
        })

I get the following message in the console when navigating to the 'venues' state (even though the redirect works, and the correct state is initiated):

TypeError: Cannot read property '@' of null
    at updateView (angular-ui-router.js:3953)
    at angular-ui-router.js:3924
    at Scope.$get.Scope.$broadcast (angular.js:14874)
    at Object.load (angular-ui-router.js:3678)
    at Object.injectables.$template (angular-ui-router.js:3554)
    at Object.invoke (angular.js:4219)
    at proceed (angular-ui-router.js:474)
    at invoke (angular-ui-router.js:470)
    at study (angular-ui-router.js:449)
    at $Resolve.resolve (angular-ui-router.js:553)

I'm using version 0.2.15, but I've also tried 0.2.13 and the 1.0 preview, and the result is the same.

Any idea what might be the issue? Do you need more information regarding my setup or dependencies?

ssc-hrep3 commented 8 years ago

Same here: When calling $state.go('anotherState'); in the onEnter function of a state, it throws this exception. Is it possible to somehow catch this exception, because it does not seem to be fixed in the 0.x.x versions?

ghost commented 8 years ago

@ssc-hrep3 there is a solution to this problem here: http://stackoverflow.com/questions/28348050/prevent-hitting-child-states-ui-router

ssc-hrep3 commented 8 years ago

@darrais Thank you for the link! I could resolve my issue with that.

pdvorchik commented 8 years ago

For anyone else who chances upon this in the future, here's a quick fix that's much more simple than the stackoverflow linked above.

Include $state and fire the state.go after the transition completes

onEnter: ['$state', function($state){
    if (myCondition && $state.transition) {
        $state.transition.finally(() => {
            $state.go('home.my.other.state', {})
        });
    }
}]