Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 794
Naresh Avatar asked Apr 06 '16 20:04

Naresh


3 Answers

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 { }
like image 117
SoProgram Avatar answered Dec 22 '22 12:12

SoProgram


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
    }
}
like image 37
Nikhil Shah Avatar answered Dec 22 '22 12:12

Nikhil Shah


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

like image 45
nikk wong Avatar answered Dec 22 '22 11:12

nikk wong