Skip to content

Unknown provider error for a state's resolve when injecting ancestor's resolved values #482

Closed
@owenpshaw

Description

@owenpshaw

The issue only occurs during a state transition when the ancestor's resolves have loaded, but resolves in between that ancestor and the destination state have not.

The code below demonstrates the issue with three states (root, child, grandchild). Navigating from root to .child.grandchild results in an Unknown Provider error as grandchild attempts to inject a resolved value from root into its own resolve.

However, the grandchild state works just fine if navigated to from root.child or directly via url on a fresh page load.

Additionally, removing the (unused in this example) resolve from the root.child state makes the root -> .child.grandchild transition possible.

<!DOCTYPE html>
<html ng-app="ui-router-test">
<head>
</head>
<body>
  <p>Issue: Can't go from root to root.child.grandchild</p>
  <div ui-view></div>
  <textarea rows="4" cols="100">{{error}}</textarea>
  <br>
  <a target="_blank" href="#/child/grandchild">Link to grandchild</a> (State loads fine fresh in a new window)
  <script type="text/javascript" src="angular.js"></script>
  <script type="text/javascript" src="angular-ui-router.js"></script>
  <script type="text/javascript">
    angular.module('ui-router-test', ['ui.router']).
      config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
        $stateProvider.
          state('root', {
            url: '/',
            template: 'Root<br> <button ng-click="gotograndchild()">$state.go(\'.child.grandchild\')</button> (doesn\'t work)<br><button ng-click="gotochild()">$state.go(\'.child\')</button> (works) <div ui-view></div>',
            controller: ['$scope', '$state', function($scope, $state){
              $scope.gotograndchild = function(){
                $state.go('.child.grandchild');
              };
              $scope.gotochild = function(){
                $state.go('.child');
              };
            }],
            resolve: {
              root_value: [function(){
                return 'Root Value';
              }]
            }
          }).
          state('root.child', {
            url: 'child',
            template: 'Child<br> <button ng-click="gotograndchild()">$state.go(\'.grandchild\')</button> (works)<div ui-view class="root.child"></div>',
            controller: ['$scope', '$state', function($scope, $state){
              $scope.gotograndchild = function(){
                $state.go('.grandchild');
              };
            }],
            resolve: {
              // The presence of this resolve breaks the relative transition from root to .child.grandchild
              // root.child.grandchild loads fine if directly requested on a fresh page load, or if navigated to from root.child
              child_value: [function(){
                return 'Child Value';
              }]
            }
          }).
          state('root.child.grandchild', {
            url: '/grandchild',
            template: 'grandchild',
            resolve: {
              // the issue appears to be that root_value, when already resolved on root, is not available
              // during the relative transition from root to .child.grandchild when root.child's child_value is being resolved.
              grandchild_value: ['root_value', function(root_value){
                return root_value + ' : Grandchild';
              }]
            }
          });
        $urlRouterProvider.otherwise('/');
      }]).run(['$state', '$rootScope', function($state, $rootScope){
        $rootScope.$on('$stateChangeError', function(event, to, toParams, from, fromParams, error){
          $rootScope.error = error.message;
        });
        $rootScope.$on('$stateChangeSuccess', function(event, to, toParams, from, fromParams){
          $rootScope.error = '';
        });
      }]);
  </script>
</body>
</html>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions