Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
owenpshaw opened this issue Oct 4, 2013 · 5 comments
Labels

Comments

@owenpshaw
Copy link

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>
@findesk
Copy link

findesk commented Nov 8, 2013

Hi @owenpshaw. Thank you for filing this...

I too am seeing this. The issue prevents using resolves in parent.child.grandchild hierarchy. Or rather, you can't go from parent -> grandchild when the grandchild relies on resolve from parent.

Should this be linked to #73?

You can see the 'Unknown Provider' error in the debugger (as $stateChangeError is gobbling the Error.message so not getting to the console)

@nateabele
Copy link
Contributor

Please follow the guidelines for reporting an issue.

@findesk
Copy link

findesk commented Nov 8, 2013

here's a plunker using the example from owenpshaw

http://plnkr.co/edit/Ugf52Viobb9r1QYLjGZy?p=preview

you can see the error in chrome console, breaking on 1071.

(how were guidelines not followed? to avoid for the future)

@nateabele
Copy link
Contributor

You just followed them. Thanks. :-)

@timkindberg
Copy link
Contributor

Dupe of #702

@christopherthielen christopherthielen removed this from the 1.5.0 milestone Nov 16, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants