1

I have an app

/// <reference path="../Scripts/angular.d.ts" />
/// <reference path="testCtrl.ts" />
/// <reference path="testSvc.ts" />
angular.module('testApp', []);
angular.module('testApp').constant('url','http://whatever');
angular.module('testApp').factory(
'testSvc', ['$http', 'url', testApp.testSvc]);
angular.module('testApp').controller(
'testCtrl', ['testSvc', testApp.testCtrl]);

and a controller

/// <reference path="../Scripts/angular.d.ts" />
/// <reference path="testSvc.ts" />
module testApp{
export class testCtrl {
    public someText:string;
    public httpData:any;
    public urlName:string;
    private data:IData;

    static $inject = ['testSvc'];

    constructor(testSvc) {
        this.someText = 'I am in scope'
        this.data = testSvc.getData();
        this.httpData = {
            putFunc: this.data.putFunc,
            expectPUTFunc: this.data.expectPUTFunc
        }
        this.urlName = this.data.urlName;
    }
}}

and a service

/// <reference path="../Scripts/angular.d.ts" />
/// <reference path="testCtrl.ts" />
interface IData{
urlName:string;
putFunc:string;
expectPUTFunc:string;
}
module testApp{
export class testSvc {
    public data:IData;



    static $inject = ['$http', 'url'];

    constructor(private $http, url) {
        this.data = {
            urlName:url,
            putFunc: typeof $http.put,
            expectPUTFunc: typeof $http.expectPUT
        }
    }

    getData(){
        return this.data;
    }
}}

and these script declarations in my html

<script type="text/javascript" src="../Scripts/angular.js"></script>
<script src="testSvc.js"></script>
<script src="testCtrl.js"></script>
<script src="testApp.js"></script>

When I run this app the controller never receives its dependency on testSvc.getData() because testSvc is undefined. Where am I going wrong?

1
  • Why are you layering your own modules on top of Angular? What benefit do you get from this extra layer of complexity, additional global state, and semantic duplication?. Commented Jan 27, 2016 at 5:40

2 Answers 2

3

A factory must return a service factory function, but you are returning the Service class without instantiating it. You need to change your code to create an instance that passes in the $http and the url, like this:

angular.module('testApp').factory('testSvc', 
  ['$http', 'url', ($http, url) => new testApp.testSvc($http, url)]);

Also just a note, but you haven't specified the return type of getData() as IData so this will create a warning. getData() : IData

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, thank you. I was following a ts-ng template I found on GitHub here (github.com/santialbo/AngularJS-TypeScript-Project-Template) and the application has a register service function which registered the service with services.push(() => new app.services[className]()); That works if the service has no dependencies but I don't thinks many do. I couldn't figure what was wrong. Also thanks for the type correction. I just can't get used to TypeScript having types after the variable or function rather than before.
2

You could just leave your testSvc class the same, and use a service(class) instead of a factory(fn). A service registers your constructor function, so you don't have to new it and provide your injected services in three different places.

angular.module('testApp').service('testSvc', testApp.testSvc);

Comments

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.