Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 7. NullInjectorError: No provider for HttpClient! Even when app.module has HttpClientModule. How to fix it?

I am using Angular 7, and I am trying to use a service that uses HttpClient to call an API link from my APIController in my .Net Core MVC application. Whenever I tried to test in the cmd window after typing in ng test, it gives me an error, and it's only for the service I'm trying to fix:

ProductService should be created
Error: StaticInjectorError(DynamicTestModule)[HttpClient]: 
  StaticInjectorError(Platform: core)[HttpClient]: 
    NullInjectorError: No provider for HttpClient!

Here's how I wrote the code in the following files below:

product.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { Product } from '../product';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  productsUrl = "api/ProductsAPI";

  constructor(private http: HttpClient) { }

  getProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(this.productsUrl)
      .pipe(
        catchError(this.handleError<Product[]>('getProducts'))
      );
  }

  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      // TODO: send the error to remote logging infrastructure
      console.error(error); // log to console instead

      //// TODO: better job of transforming error for user consumption
      //this.log(`${operation} failed: ${error.message}`);

      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }
}

The product.service file has HttpClient in it, and I read that it doesn't work unless HttpClientModule is in the import section of app.module file, and the product.service class is in the providers section.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { ProductsComponent } from './products/products.component';

import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { ProductService } from './products/product.service';

@NgModule({
  declarations: [
    AppComponent,
    ProductsComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    AppRoutingModule
  ],
  providers: [ProductService],
  bootstrap: [AppComponent]
})
export class AppModule { }

It still gives me a 'No provider for HttpClientModule' error. I want to use the product.service, and import it into another component.

Does anyone have any suggestions or answers on how to remedy this problem?

like image 874
J. Zacka Avatar asked Apr 12 '19 08:04

J. Zacka


People also ask

Which module do we need to import to use the HttpClient service?

Before you can use HttpClient , you need to import the Angular HttpClientModule . Most apps do so in the root AppModule . You can then inject the HttpClient service as a dependency of an application class, as shown in the following ConfigService example.

What is the difference between HttpClient and HttpClientModule?

Answer: They both support HTTP calls but HTTP is the older API and will eventually be deprecated. The new HttpClient service is included in the HttpClientModule that used to initiate HTTP request and responses in angular apps. The HttpClientModule is a replacement of HttpModule.

Which declares HttpClient has not been processed correctly by Ngcc?

This likely means that the library (@angular/common/http) which declares HttpClientModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so.


1 Answers

I have a way to remove the nullInjetorError problem. I thought that I have to put the HttpClientModule class in the import section of the app.module.ts file for the product.service file, but it turns out that I have to import it into the import section of the spec file, product.service.spec.ts.

product.service.spec.ts

describe('ProductService', () => {
  beforeEach(() => TestBed.configureTestingModule({
    declarations: [ProductsComponent],
    imports: [HttpClientModule]
  })
  );

And when that problem still persists in the product.component, I added the HttpClientModule class into the import section of product.component.spec.ts file,m and it fixed the problem.

product.component.spec.ts

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ProductsComponent],
      imports: [HttpClientModule]
    })
    .compileComponents();
  }));

I didn't need to add the HttpClientModule class into the import section of app.module.ts, I just needed to add it to the import section of the spec files, and that resolved my problem with the 'NullInjectorError: No provider for HttpClient.' problem.

I hope this can help for those who encounter the same problem.

like image 190
J. Zacka Avatar answered Oct 20 '22 10:10

J. Zacka