Inject Dependencies in Static Factory in Typescript
I have a service written in typescript as a class. In this class, I define a static Factory that I inject dependencies.
When I shrink my application the dependencies shrink and I get an undefined provider error.
Here is my service:
export class TInterceptor {
public static $inject = ['$q', '$rootScope'];
public static Factory($q:ng.IQService, $rootScope:ng.IRootScopeService)
{
return new TInterceptor($q, $rootScope);
}
constructor(private $q:ng.IQService, private $rootScope:ng.IRootScopeService){}...}
Service called here:
angular
.module('t')
.config(config);
function config($httpProvider:ng.IHttpProvider)
{
$httpProvider.interceptors.push(TInterceptor.Factory);
}
My question is, how can I make sure that dependencies are protected from being overwritten when compressing my code?
source to share
Register factory. i.e,
angular.module('myapp').factory('interceptorFactory', ['$q','$rootScope',TInterceptor.Factory]);
and in the config block specify the factory name:
$httpProvider.interceptors.push('interceptorFactory');
Or feed an array (suppose it should work as well as it internally uses $injector.invoke
, it is not a string)
$httpProvider.interceptors.push(['$q','$rootScope', TInterceptor.Factory]);
You also forgot the explicit annotation in the block config
.
.config(['$httpProvider', config]);
source to share
EDIT: Update for Typescript 1.6
Now that Typescript 1.6 is out, with support for class expressions, you can directly use a closed class expression to use your injections:
angular.module('myApp')
.factory('MyFactory', function($q, $http) {
return class {
constructor(data) {
// Here you have access to $q and $http
}
}
})
Typescript 1.5
Typescript not allowing class expressions at this point until version 1.6, I personally use this syntax:
class MyClass {
constructor(
private $q: ng.IQService,
private $http: ng.IHttpService
data) {
}
}
Then I use the standard Angular factory definition, which allows ng-annotate to be used at build time, and I return the class with a factory before returning it:
angular.module('myApp')
.factory('MyFactory', function($q, $http) {
var factory = MyClass
// Return curried MyClass
return Function.prototype.bind.apply(factory,
Array.prototype.concat.apply([factory], arguments))
});
The return line is equivalent to:
return MyClass.bind(MyClass, $q, $http)
This is less readable, but will prevent you from writing your dependencies twice every time you change them.
Or, if you have Lodash or Underscore, you can do it in a more elegant way:
return _.curry(MyClass).apply(this, arguments)
Then I can instantiate the class only by providing the data I need:
new MyFactory(data)
source to share