If I use es6/7 (babel - stage 1) instead of TypeScript, how are services, and specifically Http, injected?
Here\'s my component JS:
import {Compone
Since you have @Decorators
enabled in Babel
...I'll fine-tune this answer to work with your specific setup.
1. You're missing HTTP_PROVIDERS
The HTTP_PROVIDERS constant includes a number of functions required to handle HTTP requests/responses.
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'login',
providers: [ HTTP_PROVIDERS ]
})
2. You need to desugar the DI (Dependency Injection) syntax
As mentioned in @alexpods' answer.
Remove the static typing
constructor(http) {
@Inject handles DI implicitly but is only supported in Angular2+Typescript. Since you're using Angular2+ES6 you need to attach a static getter parameter to your class to provide the ES6-specific equivalent.
static get parameters() {
return [[Http]];
}
3. You need to bind the Http instance to your class in the constructor
By doing this, it will become accessible in your authenticate()
method.
constructor(http) {
this.http = http;
console.log('http', this.http);
}
...and the full implementation:
import {Component, Inject, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'login',
// required for Http
providers: [ HTTP_PROVIDERS ]
})
@View({
templateUrl: './components/login/login.html',
styleUrls: ['components/login/login.css'],
directives: [CORE_DIRECTIVES],
encapsulation: ViewEncapsulation.Emulated
})
export class Login {
constructor(http) {
// bind http to your class during construction
// so it's available to authenticate()
this.http = http;
}
// Angular2 DI desugar'd
static get parameters() {
return [[Http]];
}
authenticate(username, password) {
this.http.get('/login');
}
}
Aside: I know for a fact this works because I'm using it for the <ng2-markdown>
component on EvanPlaice.com.
With babel-plugin-angular2-annotations, you can inject services with constructor parameter type annotations just like TypeScript.
Install babel plugins:
npm install -D babel-plugin-angular2-annotations babel-plugin-transform-decorators-legacy babel-plugin-transform-class-properties babel-plugin-transform-flow-strip-types babel-preset-es2015
.babelrc:
{
"plugins": [
"angular2-annotations",
"transform-decorators-legacy",
"transform-class-properties",
"transform-flow-strip-types"
],
"presets": [
"es2015"
]
}
and voila!
import {Component, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
import {Http} from 'angular2/http';
@Component({
selector: 'login'
})
@View({
templateUrl: './components/login/login.html',
styleUrls: ['components/login/login.css'],
directives: [CORE_DIRECTIVES],
encapsulation: ViewEncapsulation.Emulated
})
export class Login {
constructor(http: Http) {
console.log('http', http);
this.http = http;
}
authenticate(username, password) {
this.http.get('/login');
}
}
Note that the type signature is used only for a hint for dependency injection and not used for type-checking.
How I've already answered it here, If you write code in ES7, use static getter for parameters
property to specify injections into constructor
of your component. For example:
import { Http } from 'angular2/http';
// other imports ...
// component decorators ...
export class Login {
static get parameters() {
return [[Http]];
}
constructor(http) {
this.http = http;
console.log('http', http);
}
// other methods
}
I think it most concise method at this moment.
Remember there is no proposal to support parameter decorators in ES7 at this moment (for example see this issue for Babel).
Method from the official API Review works for me:
import {Http, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'http-app',
viewProviders: [HTTP_PROVIDERS],
templateUrl: 'people.html'
})
class PeopleComponent {
constructor(http: Http) {
http.get('people.json')
.map(res => res.json())
.subscribe(people => this.people = people);
}
}