Injecting resolves into directive controllers

All we need is an easy explanation of the problem, so here it is.

I’m using AngularUI router (0.2.13) and have a state defined as such

.state('foo', { 
    template:'<div some-directive></div>', 
    resolve: {
        foo: function(SomeService) {
            return SomeService.something().promise;
        }
    }
})

and a directive like this:

app.directive('someDirective', function(){
     return {
         controller: function(data) {
           // I want `data` to be injected from the resolve... 
           // as it would if this was a "standalone" controller
         }
     }
})

but this doesn’t work – the data parameter causes an UnknownProvider error. Defining the directive controller independently and setting it by name in the directive has the same result.

I more or less get why this is happening, but have two questions:

  1. is there a way to do what I’m trying to do?
  2. should I be trying to do it, or have I slipped into an antipattern here?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You can’t use resolves in directives, but you can pass the result resolved in the state down to the directive which I think accomplishes what you’re looking for.

You’d want to update your state definition to include a controller and set a parameter on the directive:

.state('foo', { 
   template:'Test<div some-directive something="foo"></div>',
   url: 'foo',
   resolve:{
       foo:function(SomeService){
           return SomeService.something();
       }
   },
   controller: function($scope, foo){
     $scope.foo = foo;
   }
})

Then update the directive to use this parameter:

.directive('someDirective', function(){
     return {
         controller: function($scope) {
           // I want `data` to be injected from the resolve... 
           // as it would if this was a "standalone" controller
           console.log('$scope.something: '+ $scope.something);
         },
         scope: {
           something: '='
         }
     };
})

Here’s a sample plunker: http://plnkr.co/edit/TOPMLUXc7GhXTeYL0IFj?p=preview

Method 2

They simplified the api. See this thread:

https://github.com/angular-ui/ui-router/issues/2664#issuecomment-204593098

in 0.2.19 we are adding $resolve to the $scope, allowing you to do "route to component template" style

template: <my-directive input="$resolve.simpleObj"></my-directive>,

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply