1

I want to move some of the repetitive logic out in a reusable service, which must be available in a config phase. And possibly have access to $xxxProvider dependency injections too. Is such thing possible? Can one do this with factory/provider/service/constant ?

To be specific, when I define my routes with ui-router, I noticed that routes for CRUD are all the same, except for the names of the resources. So i'd like to move this logic of configuring a CRUD route somewhere to make route definitions more DRY.

Roman Kolpak
  • 1,942
  • 21
  • 25

1 Answers1

2

For accessing your service provider in the config block, this should work just fine:

app.service('myService', function (/* dependencies */) {
  // service stuff..

  return this; 
});

app.config(function ($provide) {
  $provide.decorator('myService', function ($delegate) {
    // $delegate refers to 'myService'. 
    // You can modify its behaviour and what not in here.

    return $delegate;
  });
});

I'm not crystal clear on what you are looking for, but this 'just works'.

Do note, that the service registration needs to come before the config block if they reside in the same file. A way to overcome this, would be to extract your service into a separate module and inject it as a dependency to your main module. Something like this:

var serviceModule = angular.module('serviceModule', []);

serviceModule.service('myService', function () {});

var mainModule = angular.module('main', ['serviceModule']);

mainModule.config(function ($provide) {
  $provide.decorator('myService', function ($delegate) {});
});

JsBin: http://jsbin.com/pasiquju/2/edit

Edit

I've now put together a rough example of how you could do the following:

  1. Register your own custom provider constructor, that returns an object.
  2. Inject another provider into your own provider, passing through functionality from one constructor to another.
  3. Register a secondary service, that gets injected into the provider constructor.
  4. Pass some more functionality from the app.config block to your provider constructor.
  5. Inject the instance returned by the constructor into a controller.
  6. Output the end data from the instance returned by the constructor, with args.

This should cover the needs specified:

  • Prone to DI, from providers.
  • Prone to DI, from services.
  • Available during config phase.

JsBin: http://jsbin.com/jenumobi/2/edit

And here's the documentation for the provider shorthand methods, and how they differ. As you can clearly see, the provider core function is the one with the most options available to it - but also the hardest to work with, for obvious reasons.

I hope that will do enough for you, and give you some sort of idea on how to create your own $stateProvider extension! I've done my best to document the code in the JsBin to make it easier to understand just how it all ties together.

  • Thanks a lot for you answer. Please take a look at this fiddle to maybe have more Idea of what I'm trying to accomplish: http://jsbin.com/hubayefi/1/edit As you can see `constant` is available at config phase, but I doesn't allow dependency injections into it, which limits the stuff I can do inside it. I'm looking for an equivalent to `constant`, but with DI. Maybe that's just stupid though :( – Roman Kolpak Jul 25 '14 at 12:23
  • Yeah, unfortunately that is not possible with value/constant.`value` can recieve DI and be modified in a decorator, but it is not available during config. `constant` is available during config, but cannot recieve DI or be modified by a decorator. There is no middleground that I'm aware of. –  Jul 25 '14 at 14:49
  • If you create your own `provider` however, then I suppose you could have access to it during config phase, and apply DI to it with a decorator. Never done that myself though. –  Jul 25 '14 at 14:53
  • 1
    And just now I realise that you **do** have access to other providers when declaring your own provider. I'll whip up a JsBin when I get home. Won't be long. –  Jul 25 '14 at 15:01
  • You are most welcome. It's a ton of fun to experiment with some more elaborate tasks in angular. See my updated answer for a solution that *should* fit your needs. –  Jul 25 '14 at 15:50