If I use es6/7 (babel - stage 1) instead of TypeScript, how are services, and specifically Http, injected?
Here's my component JS:
import {Component, Inject, 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(@Inject(Http) http) {
console.log('http', http);
}
authenticate(username, password) {
// this.http.get('/login');
}
}
I have tried:
export class Login {
constructor(@Inject(Http) http) {
console.log('http', http);
}
}
/********************/
@Inject(Http)
export class Login {
constructor(http) {
console.log('http', http);
}
}
/********************/
export class Login {
constructor(Http: http) {
console.log('http', http);
}
}
/********************/
export class Login {
constructor(http = Http) {
console.log('http', http);
}
}
/********************/
export class Login {
constructor(Http) {
this.http = new Http()
console.log('http', this.http);
}
}
/********************/
export class Login {
constructor(http = new Http()) {
console.log('http', http);
}
}
All but the first compiles. Others give me access to either the Http class or an http instance. But none works.
I tried to following the discussion referenced by Eric Martinez in his comment. Login.js now:
import {Component, Inject, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2';
import {HTTP_BINDINGS, Http, BaseRequestOptions, RequestOptions, RequestMethods} from 'angular2/http';
@Component({
selector: 'login'
})
@View({
templateUrl: './components/login/login.html',
styleUrls: ['components/login/login.css'],
directives: [CORE_DIRECTIVES],
encapsulation: ViewEncapsulation.Emulated,
bindings: [Http]
})
export class Login {
constructor(http) {
this.http = http;
console.log('http', http);
}
authenticate(usernameEl, passwordEl) {
var username = usernameEl.value;
var password = passwordEl.value;
console.log('username', username, password);
// this.http.get('/login');
}
}
Login.parameters = [Http];
It compiles now but generates the following error:
Uncaught (in promise) NoBindingError {message: "No provider for Http! (Login -> Http)", stack: "Error: DI Exception↵ at NoBindingError.BaseExce…or._new (http://localhost:3000/bundle.js:7319:22)", keys: Array[2], injectors: Array[2]}constructResolvingMessage: (keys)arguments: (...)caller: (...)length: 1name: ""prototype: Object__proto__: ()context: (...)injectors: Array[2]0: Injector1: Injectorlength: 2__proto__: Array[0]keys: Array[2]message: "No provider for Http! (Login -> Http)"stack: "Error: DI Exception↵ at NoBindingError.BaseException [as constructor] (http://localhost:3000/bundle.js:8400:24)↵ at NoBindingError.AbstractBindingError [as constructor] (http://localhost:3000/bundle.js:9066:17)↵ at new NoBindingError (http://localhost:3000/bundle.js:9102:17)↵ at Injector._throwOrNull (http://localhost:3000/bundle.js:7469:20)↵ at Injector._getByKeyDefault (http://localhost:3000/bundle.js:7516:22)↵
at Injector._getByKey (http://localhost:3000/bundle.js:7461:26)↵ at Injector._getByDependency (http://localhost:3000/bundle.js:7447:26)↵
at Injector._instantiate (http://localhost:3000/bundle.js:7339:37)↵
at Injector._instantiateBinding (http://localhost:3000/bundle.js:7330:26)↵ at Injector._new (http://localhost:3000/bundle.js:7319:22)"proto: __
How I've already answered it here, If you write code in ES7, use static getter for
parameters
property to specify injections intoconstructor
of your component. For example: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).
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.
2. You need to desugar the DI (Dependency Injection) syntax
As mentioned in @alexpods' answer.
Remove the static typing
@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.
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....and the full implementation:
Aside: I know for a fact this works because I'm using it for the
<ng2-markdown>
component on EvanPlaice.com.Method from the official API Review works for me:
With babel-plugin-angular2-annotations, you can inject services with constructor parameter type annotations just like TypeScript.
Install babel plugins:
.babelrc:
and voila!
Note that the type signature is used only for a hint for dependency injection and not used for type-checking.