9

I have written an angular provider that needs $injector service to be injected in the $get function but I do not know how to write this in typescript and make it minification safe. Something like static $injector = ['']; notation that works for services and controllers.

Typescript:

export class ApiProvider implements IApiProvider {
    private baseRoute: string = '';
    private endpoints: { [name: string]: IApiEndPointConfig };

    static $inject = ['$injector']; //THIS DOES NOT WORK FOR PROVIDERS
    constructor() {
        this.baseRoute = '';
        this.endpoints = {};
    }

            // MORE CODE

    $get = ($injector: ng.auto.IInjectorService): { [name: string]: ApiEndpoint } => {
        var api: { [name: string]: ApiEndpoint } = {};
        var self:ApiProvider = this;
        angular.forEach(this.endpoints, (endpointConfig, name) => {
            api[name] = $injector.instantiate(ApiEndpoint, {
                baseRoute: self.baseRoute,
                endpointConfig: endpointConfig
            });
        });

        return api;
    };
}

The generated javascript for the $get function is:

this.$get = function ($injector) {
    var api = {};
    var self = _this;
    angular.forEach(_this.endpoints, function (endpointConfig, name) {
        api[name] = $injector.instantiate(Model.ApiEndpoint, {
            baseRoute: self.baseRoute,
            endpointConfig: endpointConfig
        });
    });

    return api;
};

And what I want it to be is something like:

this.$get = ['$injector', function ($injector) {
    var api = {};
    var self = _this;
    angular.forEach(_this.endpoints, function (endpointConfig, name) {
        api[name] = $injector.instantiate(Model.ApiEndpoint, {
            baseRoute: self.baseRoute,
            endpointConfig: endpointConfig
        });
    });

    return api;
}];

1 Answer 1

16

I think I got it. After reading the $injector documentation more closely I found that the $inject string array notation can be used on any function. Thus I did something like:

constructor(){
   this.$get.$inject = ['$injector'];
}

$get = ($injector: ng.auto.IInjectorService): { [name: string]: ApiEndpoint } => {
    //using $injector
};

which produces:

this.$get = function ($injector) {
   //using $injector                    
};

this.$get.$inject = ['$injector'];
Sign up to request clarification or add additional context in comments.

5 Comments

+1 This is the correct way to do this and the reason why github.com/borisyankov/DefinitelyTyped/blob/master/angularjs/… exists in the definition ;)
Great find @basarat. I will have to start looking in the def files more.
Talk about access to the "source". Your Typescript+Angular contributions are much appreciated (I've seen you answer almost all related questions in SO). Nice typescript videos on youtube also.
it's so funny, when you see what you did here, it's like, duh, of course that's how you should do it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.