Angular 2 service not being injected into component

Michael Oryl picture Michael Oryl · Dec 18, 2015 · Viewed 21.2k times · Source

I have a service defined in my Angular2 (2.0.0-beta.0) application. It's something like this:

import {Injectable} from "angular2/core";

@Injectable()
export class MyService {
    constructor() {

    }

    getSomething() {
        return 'something';
    }
}

I have it listed in my bootstrap() function in my main app file so that it should be made available to my code in general:

bootstrap(App, [MyService, SomeOtherService, ROUTER_DIRECTIVES[);

Sometimes I can't use the service in a component, even though I have something like myService:MyService in the component constructor() function, like this:

import {MyService} from '../services/my.service';

@Component({
    selector: 'my-component',
    directives: [],
    providers: [],
    pipes: [],
    template: `
    <div><button (click)="doStuff()">Click Me!</button></div>
    `
})
export MyComponent {
    constructor(myService:MyService) {} // note the private keyword

    doStuff() {
        return this.myService.getSomething();
    }
}

In other places it works fine. In places where it doesn't work, I get a message like if I try to access it:

EXCEPTION: TypeError: Cannot read property 'getSomething' of undefined

It basically means the service was not injected.

What is causing it to not be injected?

Answer

Romain picture Romain · Dec 18, 2015

This behaviour is totally normal.

In the constructor method of the component when you don't add the private or public keyword the myService variable is evaluated as a local variable, so it's destroyed at the end of the method call.

When you add private or public keyword, TypeScript will add the variable to the class property, so you can later call the property with this keyword.

constructor(myService: MyService) {
  alert(myService.getSomething());
  // This will works because 'myService', is declared as an argument
  // of the 'constructor' method.
}

doStuff() {
  return (this.myService.getSomething());
  // This will not works because 'myService' variable is a local variable
  // of the 'constructor' method, so it's not defined here.
}