Comment - I managed to fix this issue, see in the bottom of this post
I am upgrading my Angular 1.X application using UpgradeAdapter (ngUpgrade). I added a new Angular 2.0 service which I call from my Angular 2.0 Component:
Service:
import {Inject} from 'angular2/core';
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
export default class MyService {
_http;
constructor(http: Http) {
this._http = http; //http is undefined here
}
getData(): Observable<any> {
return this._http.get(someUrl);
}
}
Inside my bootstrap.ts
I have:
declare var angular: any;
import {UpgradeAdapter} from 'angular2/upgrade';
import {Http} from 'angular2/http';
let adapter = new UpgradeAdapter();
adapter.addProvider(Http);
//.....
adapter.bootstrap(document.body, ['myApp']);
What am I doing wrong here?
EDIT:
I am injecting another service (Angular 1.X upgraded service) to my Angular 2.0 service, and it does work:
import {Inject} from 'angular2/core';
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
export default class MyService {
_http;
_dataService;
constructor( @Inject('dataService') dataService, http: Http) {
this._http = http; //http is undefined here
this._dataService = dataService; //dataService is defined!!
}
getData(): Observable<any> {
return this._http.get(someUrl);
}
}
Bootstrap.ts:
declare var angular: any;
import {UpgradeAdapter} from 'angular2/upgrade';
import {Http} from 'angular2/http';
let adapter = new UpgradeAdapter();
adapter.addProvider(Http);
adapter.upgradeNg1Provider('dataService');
adapter.bootstrap(document.body, ['myApp']);
EDIT 2:
When looking at my ES5 transpired code I found this code:
MyService = __decorate([
core_1.Injectable(),
__param(0, core_1.Inject('dataService'))
], MyService);
return MyService;
As you can see - no http
injection to MyService
. When changing my service constructor to use this syntax
constructor( @Inject('dataService') dataService, @Inject('Http') http)
Now I am getting the following error:
Error: No provider for Http!
Solution for the problem:
So I finally succeed, using a clue from @PierreDuc response:
I changed the constructor for MyService to be:
constructor( @Inject('dataService') dataService, @Inject(Http) http)
And I added HTTP_PROVIDERS
as a provider to my component (which uses the service):
(inside my ng 2 component:)
providers: [MyService, HTTP_PROVIDERS]
No need for @Injectable
or addProvider
inside my bootstrap.
I do not fully understand why is this happening and why this solution worked. Will love to have it explained if someone here knows it.
Solution Edit:
After a little reading, I now understand DI better. I can use the addProvider(HTTP_PROVIDERS)
instead of defining a provider for each component (it will be available for all components). The only mystery left is why injecting private http: Http
doesn't work while @Inject(Http) http
does work. Any idea???
You should add the HTTP_PROVIDERS
in the bootstrap, and not just Http
. Try this for bootstrap.ts
declare var angular: any;
import {UpgradeAdapter} from 'angular2/upgrade';
import {HTTP_PROVIDERS} from 'angular2/http';
let adapter = new UpgradeAdapter();
adapter.addProvider(HTTP_PROVIDERS);
//.....
adapter.bootstrap(document.body, ['myApp']);
edit
And above that MyService.ts
must have an @Injectable()
decorator to let angular know it has to inject its dependencies. The reason the injection of the dataService
worked is because you used the decorator @Inject
. Try this for MyService.ts
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
@Injectable()
export default class MyService {
constructor(private _http: Http) {}
getData(): Observable<any> {
return this._http.get(someUrl);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With