Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for dependency injection in an AngularJS service with TypeScript

I find dependency injection for AngularJS services in TypeScript to be somewhat cumbersome. Currently, I define a factory method inside my service class, and have to repeat all dependency injection arguments three times:

class MyService {
    public static Factory($rootScope, myController) {       // 1st time
        return new MyService($rootScope, myController);     // 2nd time
    }
    constructor(public $rootScope, public myController) {}  // 3rd time
}
myModule.factory('myService', MyService.Factory);

I would like to do the following, but that does not seem to work:

class MyService {
    constructor(public $rootScope, public myController) {}  // only once
}
myModule.factory('myService', MyService);

This approach works fine for controllers, but not so for services. Is there a better way?

Thanks in advance!

like image 836
Vincent Avatar asked Nov 21 '13 15:11

Vincent


People also ask

Does TypeScript support Dependency Injection?

The D letter in SOLID is the Dependency Inversion principle. It helps to decouple modules from each other so that you can easily swap one part of the code for another. One of the techniques that helps to follow this principle is Dependency Injection.

Can TypeScript be used with AngularJS?

Guide to using TypeScript in AngularJS applications. Supporting older AngularJS applications doesn't mean you can't take advantage of modern tools like TypeScript. Not every file in your application needs to be written in TypeScript at once, you just can rename all your JavaScript files to have a . ts extension.

How is Dependency Injection done in AngularJS?

Dependency injection (DI) is a paradigm. The way it works in Angular is through a hierarchy of injectors. A class receives its resources without having to create or know about them. Injectors receive instruction and instantiate a service depending on which one was requested.

How would you implement Angular Dependency Injection Everything you need to know?

The first step is to add the @Injectable decorator to show that the class can be injected. The next step is to make it available in the DI by providing it. A dependency can be provided in multiple places: At the Component level, using the providers field of the @Component decorator.


2 Answers

You should user service not factory :

class MyService {
    constructor(public $rootScope) {}  // only once
}
myModule.service('myService', MyService);
like image 183
basarat Avatar answered Oct 11 '22 00:10

basarat


You could simply use angular's injector to create your controller instead of having a factory method.

Here is a sample in typescript

/// <reference path='d.ts/DefinitelyTyped/angularjs/angular.d.ts' />

class MyCtrl {
  public phrase: string;
  constructor($window) {
    this.phrase = 'I was loaded by injector';
  }

  speak() {
    alert(this.phrase);
  }
}

function main() {
  var injector = angular.injector(['ng']);
  var ctrl = injector.instantiate(MyCtrl);
  ctrl.speak();
}

And a fiddler to prove it works: http://jsfiddle.net/UPv5j/3/

like image 35
Saulo Vallory Avatar answered Oct 11 '22 00:10

Saulo Vallory