epeleg
epeleg

Reputation: 10915

dependency injection into decorator functions in angularJS

When using angularJS you can register a decorating function for a service by using the $provide.decorator('thatService',decoratorFn).

Upon creating the service instance the $injector will pass it (the service instance) to the registered decorating function and will use the function's result as the decorated service.

Now suppose that thatService uses thatOtherService which it has injected into it.

How I can I get a reference to thatOtherService so that I will be able to use it in .myNewMethodForThatService() that my decoratorFN wants to add to thatService?

Upvotes: 3

Views: 2689

Answers (1)

gkalpak
gkalpak

Reputation: 48211

It depends on the exact usecase - more info is needed for a definitive answer.
(Unless I've misunderstood the requirements) here are two alternatives:

1) Expose ThatOtherService from ThatService:

.service('ThatService', function ThatServiceService($log, ThatOtherService) {
  this._somethingElseDoer = ThatOtherService;
  this.doSomething = function doSomething() {
    $log.log('[SERVICE-1]: Doing something first...');
    ThatOtherService.doSomethingElse();
  };
})
.config(function configProvide($provide) {
  $provide.decorator('ThatService', function decorateThatService($delegate, $log) {
    // Let's add a new method to `ThatService`
    $delegate.doSomethingNew = function doSomethingNew() {
      $log.log('[SERVICE-1]: Let\'s try something new...');

      // We still need to do something else afterwards, so let's use
      // `ThatService`'s dependency (which is exposed as `_somethingElseDoer`)
      $delegate._somethingElseDoer.doSomethingElse();
    };

    return $delegate;
  });
});

2) Inject ThatOtherService in the decorator function:

.service('ThatService', function ThatServiceService($log, ThatOtherService) {
  this.doSomething = function doSomething() {
    $log.log('[SERVICE-1]: Doing something first...');
    ThatOtherService.doSomethingElse();
  };
})
.config(function configProvide($provide) {
  $provide.decorator('ThatService', function decorateThatService($delegate, $log, ThatOtherService) {
    // Let's add a new method to `ThatService`
    $delegate.doSomethingNew = function doSomethingNew() {
      $log.log('[SERVICE-2]: Let\'s try something new...');

      // We still need to do something else afterwatds, so let's use
      // the injected `ThatOtherService`
      ThatOtherService.doSomethingElse();
    };

    return $delegate;
  });
});

You can see both approaches in action in this demo.

Upvotes: 4

Related Questions