Naresh
Naresh

Reputation: 25763

Injecting http in a service gives "No provider for Http!" error

Angular version: 2.0.0-beta.13

I am trying to inject http into a service:

@Injectable()
export class GithubService {
    ...
    constructor(private http: Http) {
    }
}

I have listed HTTP_PROVIDERS as a provider in the root component of my application, so this provider should be available to any component in my application:

@Component({
  providers: [HTTP_PROVIDERS],
})
export class AppComponent {}

However when I run this application, I get the following error:

EXCEPTION: Error: Uncaught (in promise): No provider for Http! (HttpReqComponent -> GithubService -> Http)

What am I doing wrong?

Edit

I changed providers to viewProviders and the error is now gone!

@Component({
  viewProviders: [HTTP_PROVIDERS],
})
export class AppComponent {}

However, I cannot explain why this is working. http is not being accessed by any view directly. It is only accessed inside GithubService. So why do I have to declare HTTP_PROVIDERS as a viewProvider?

Edit 2

Well, I moved the providers declaration from AppComponent down to the component where I need it and now it works! So there must be some quirk in declaring it at the root level.

@Component({
    providers: [HTTP_PROVIDERS, GithubService],
})
export class HttpReqComponent { }

Actually, both providers and viewProviders works. Turns out that viewProviders is actually more restrictive and provides better encapsulation of the component. See this article for details.

Upvotes: 21

Views: 53127

Answers (4)

SoProgram
SoProgram

Reputation: 403

Following this link

Angular2/http Exception no ConnectionBackend The answer of @abreneliere is correct for me while working with Angular 2 Quickstart (https://angular.io/guide/quickstart) and i was trying to add a service to a component.

The answer: File: app.module.ts Code:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from "@angular/http";
import { AppComponent } from './app.component';

@NgModule({
    imports: [BrowserModule, HttpModule],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }

Upvotes: 20

nikk wong
nikk wong

Reputation: 8670

As of 2.0.0-rc.5 this is now:

import { HttpModule } from '@angular/http';


@NgModule({
  imports: [
    HttpModule
  ]}

https://angular.io/docs/ts/latest/guide/server-communication.html

Upvotes: 11

Jassi
Jassi

Reputation: 669

You can import { HttpModule } into a module that has your component declared, in which you are using injectable service, given module is not lazy loaded.

Upvotes: 0

micronyks
micronyks

Reputation: 55443

Its okay if you go with Providers:[HTTP_PROVIDERS] but its good to refernce HTTP_PROVIDERS into bootstrap(). You don't need to use viewProvider, it is there for some other purpose.

you have to make sure that http.dev.js has been included (via CDN/node_modules).

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.13/http.dev.js"></script> 

Then in rootComponent,

import {HTTP_PROVIDERS} from 'angular2/http';
import {GithubService} from './GithubService';

bootstrap(rootComponent,[HTTP_PROVIDERS,GithubService]);

// if you reference HTTP_PROVIDERS here globally (in bootstrap), you don't require to use providers:[HTTP_PROVIDERS] in any component. 
// same way GithubService reference has been passed globally which would create single instance of GithubService (In case if you want)

Then in GithubService ,

import {Http} from 'angular2/http';

@Injectable()
export class GithubService {
    ...
    constructor(private http: Http) {  // this will work now without any error
    }
}

Upvotes: 12

Related Questions