Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject a Factory in AngularJS using Typescript

So in plain old Angular, you would inject a Factory like so:

(function(angular){
    "use strict";

    var app = angular.module('app', []);
    app.factory('MyFactory', ['$http', function($http) {
    ....
    });
}());

Now using Typescript, I am trying to use the $inject like so:

module Services {
    export class MyFactory {
        static $inject = ['$http'];
        constructor(private $http: ng.IHttpService) {
        }
    }
}

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

app.factory('MyFactory', Services.MyFactory) //<-- This does not work, never is instantiated.

app.factory('MyFactory', ['$http', Services.MyFactory]); //<-- No deal, it has constructor dependencies

// Seems you have to do this
app.factory('MyFactory', ['$http', ($http) => new Services.MyFactory($http)]);

What is the correct way to inject factories in Angular using Typescript?

like image 838
Sam Avatar asked Sep 30 '14 04:09

Sam


3 Answers

In this todoMvc example project they declare factory functions as functions and not as a class.

module Services {
  export function MyFactory($http: ng.IHttpService): string{
     var stuff = "foo";
     return stuff;
  }
  MyFactory.$inject = ["$http"];
}

app.factory("myFactory", Services.MyFactory);

Since directives are factory functions this is the syntax we (in my project) use for directives. Then the return type of the function is ng.IDirective.

I also agree with basarat that using .service is better in your case. This is just for reference how you could write a angular factory in typescript.

like image 57
Gustav Avatar answered Oct 21 '22 10:10

Gustav


app.factory('MyFactory', Services.MyFactory) This does not work, never is instantiated.

True. This is because the function passed as a second argument (MyFactory) is never called with the new operator. If you want to use a TypeScript class you must use service and not factory.

The usage of the new operator is the only difference between a service and a factory, so there is no reason for you to use a factory. Both are singletons in AngularJS.

like image 44
basarat Avatar answered Oct 21 '22 09:10

basarat


Take this example as i had created a httpget wrapper

module portal.services {


export class apiService {


    public getData<T>(url?:string): ng.IPromise<T> {

        var def = this.$q.defer();
        this.$http.defaults.headers.common.token = window.sessionStorage[localStorageNames.bearerToken] || 'UA';
        this.$http.get(this.config.apiBaseUrl + url).then((successResponse) => {

            if(successResponse)
                def.resolve(successResponse.data);
            else
                def.reject('server error');

        }, (errorRes) => {

            def.reject(errorRes.statusText);
        });

        return def.promise;
    }


    static $inject = ['$q','$http', 'config'];

    constructor(public $q:ng.IQService,public $http:ng.IHttpService, public config:interfaces.IPortalConfig) {


    }

}



}


module portal {
   export var app:ng.IModule =angular.module('portal',[]);
    app.service(services);

}
like image 22
Pranay Dutta Avatar answered Oct 21 '22 10:10

Pranay Dutta