Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2.0 - Injected Http service is undefined

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???

like image 860
Yaniv Efraim Avatar asked Dec 24 '15 08:12

Yaniv Efraim


1 Answers

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);
  }
}
like image 130
Poul Kruijt Avatar answered Oct 09 '22 05:10

Poul Kruijt