RJB
RJB

Reputation: 2103

Inject AngularJS object as TypeScript class (methods missing)

The Angular gets some JSON from a service as part of the route resolve.

The JSON is injected into the controller as an Angular-ish deserialized object.

The properties of the object line up with the provided TypeScript class, so vm.foo.displayName is successfully displayed on the html page for example.

But I think the methods defined in the TypeScript class are nowhere to be found, so when I try to call vm.foo.run(), the console prints the error: TypeError: Object doesn't support property or method 'run'

module app.Samples {

    export class Foo {
        public typeName: string;
        public displayName: string;

        public run(): void {
            alert("Running!");
        }
    }
}

module app.Samples {

     interface IFoobarScope {
         foo: Foo;
     }

     class FoobarController implements IFoobarScope {
         foo: Foo;

         static $inject = ['foo'];
         constructor(foo: Foo) {
             var vm = this;
             vm.foo = foo;
             vm.foo.run();
         }
     }

     angular
         .module('app.Samples')
         .controller('app.Samples.FoobarController', FoobarController);
 }

Upvotes: 1

Views: 806

Answers (1)

JLRishe
JLRishe

Reputation: 101730

Yes, as far as AngularJS is concerned, it's just passing any old object into your controller function. TypeScript provides the syntactical sugar for the Foo class within your code, but it's not going to give an object a run() method if it doesn't have one.

You could create a copy constructor for your Foo type:

constructor(foo?: Foo) {
    if(foo) {
        this.typeName = foo.typeName;
        this.displayName = foo.displayName;
    }
}

And then do this in your controller:

constructor(foo: Foo) {
    var vm = this;
    vm.foo = new Foo(foo);
    vm.foo.run();
}

Alternatively, you could skip the copy constructor approach and use angular.extend():

constructor(foo: Foo) {
    var vm = this;
    vm.foo = new Foo();
    angular.extend(vm.foo, foo);
    vm.foo.run();
}

Upvotes: 2

Related Questions