Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullInjectorError: No provider for HttpHandler! despite HttpClient/HttpClientModule being present

I'm new to an Angular-based UI project, and used vscode to generate two new components for use on the project. However, I keep getting errors whenever I push my changes to git(bitbucket) and these errors are not present when I build the project on my machine. Where do I need to provide HttpClient/HttpClientModule so that these new components can use HttpHandler?

I've added providers for HttpClientModule and HttpClient on both app.module.ts and the new components themselves.

modal-wiped-all.component.ts

import { Component, OnInit } from '@angular/core';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { Router } from '@angular/router';

import { OrganisationsApiService } from 'src/app/api/organisations/organisations-api.service';
import { HttpClient, HttpClientModule, HttpHandler } from '@angular/common/http';


@Component({
  selector: 'app-modal-wipedall',
  templateUrl: './modal-wiped-all.component.html',
  providers: [NgbActiveModal,
  OrganisationsApiService,
  HttpClientModule,
HttpClient,
]})

cleanup.component.ts

import { Component, OnInit } from '@angular/core';
 import { HttpClient, HttpClientModule, HttpHandler } from '@angular/common/http';
import { OrganisationsApiService } from 'src/app/api/organisations/organisations-api.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

import { ModalWipedAllComponent } from '../modal/modal-wiped-all/modal-wiped-all.component';



@Component({
  selector: 'app-cleanup',
  templateUrl: './cleanup.component.html',
  styleUrls: ['./cleanup.component.css'],
  providers: [OrganisationsApiService,
    NgbModal,
    HttpClientModule,
    HttpClient,

  ]
})


export class CleanupComponent implements OnInit {

  submitted: boolean;
  loading: boolean;
  deleted: number;

  constructor(
    private http: HttpClient,
    private api: OrganisationsApiService,
    private modalService: NgbModal) {

   }

app.module.ts providers

providers: [AwsApiService,
              OrganisationsApiService,
              LabsApiService,
              UsersApiService,
              UserManagementDataService,
              ConfigDataService,
              ErrorDataService,
              DeploymentResponseDataService,
              ModalOptionsComponent,
              ModalConfigurationComponent,
              ModalUndeployLabComponent,
              ModalCreatedUserComponent,
              NgbActiveModal,
              HttpClientModule,
              HttpClient,


     { provide: HTTP_INTERCEPTORS,
      useClass: HttpRequestInterceptor,
      multi: true}
    ],   

error messages:

CleanupComponent.CleanupComponent should createChrome 56.0.2924 (Linux 0.0.0)
<1s
Error: StaticInjectorError(DynamicTestModule)[HttpClient -> HttpHandler]: 
  StaticInjectorError(Platform: core)[HttpClient -> HttpHandler]: 
    NullInjectorError: No provider for HttpHandler!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get node_modules/@angular/core/fesm5/core.js:1062:1)
    at resolveToken node_modules/@angular/core/fesm5/core.js:1300:1)
    at tryResolveToken node_modules/@angular/core/fesm5/core.js:1244:1)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get node_modules/@angular/core/fesm5/core.js:1141:1)
    at resolveToken node_modules/@angular/core/fesm5/core.js:1300:1)
    at tryResolveToken node_modules/@angular/core/fesm5/core.js:1244:1)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get node_modules/@angular/core/fesm5/core.js:1141:1)
    at resolveNgModuleDep node_modules/@angular/core/fesm5/core.js:8369:1)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get node_modules/@angular/core/fesm5/core.js:9057:1)
    at resolveDep node_modules/@angular/core/fesm5/core.js:9422:1)




ModalWipedAllComponent.ModalWipedAllComponent should createChrome 56.0.2924 (Linux 0.0.0)
<1s
Error: StaticInjectorError(DynamicTestModule)[HttpClient -> HttpHandler]: 
  StaticInjectorError(Platform: core)[HttpClient -> HttpHandler]: 
    NullInjectorError: No provider for HttpHandler!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get node_modules/@angular/core/fesm5/core.js:1062:1)
    at resolveToken node_modules/@angular/core/fesm5/core.js:1300:1)
    at tryResolveToken node_modules/@angular/core/fesm5/core.js:1244:1)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get node_modules/@angular/core/fesm5/core.js:1141:1)
    at resolveToken node_modules/@angular/core/fesm5/core.js:1300:1)
    at tryResolveToken node_modules/@angular/core/fesm5/core.js:1244:1)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get node_modules/@angular/core/fesm5/core.js:1141:1)
    at resolveNgModuleDep node_modules/@angular/core/fesm5/core.js:8369:1)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get node_modules/@angular/core/fesm5/core.js:9057:1)
    at resolveDep node_modules/@angular/core/fesm5/core.js:9422:1)

I expect the project to build as it does locally, I instead get NullInjectorErrors

UPDATE: component.spec.ts files ModalWipedAll

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ModalWipedAllComponent } from './modal-wiped-all.component';

describe('ModalWipedAllComponent', () => {
  let component: ModalWipedAllComponent;
  let fixture: ComponentFixture<ModalWipedAllComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ModalWipedAllComponent ]  
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ModalWipedAllComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

CleanupComponent

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { CleanupComponent } from './cleanup.component';

describe('CleanupComponent', () => {
  let component: CleanupComponent;
  let fixture: ComponentFixture<CleanupComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ CleanupComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(CleanupComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
like image 931
Callum Martin Avatar asked Dec 27 '18 15:12

Callum Martin


2 Answers

There are few steps to achieve this -

  1. in your app.module.ts import HttpClientModule like below

    import { HttpClientModule } from '@angular/common/http';

and use it the imports array of @NgModule like below .

@NgModule({
 ...
 imports : [BrowserModule,HttpClientModule],  
 providers: [.... other services ..]
 })

HttpClientModule should be added after BrowserModule. This order is important in imports array.

  1. Remove all the imports of HttpClientModule from the components . If you are importing it at the root module then it's sufficient.

  2. Remove HttpClient from the providers array of @NgModulein the app.module.ts, it's not required . You can directly inject the instance of HttpClient in the constructor of component without adding it in providers.

  3. if you are using ng-bootstrap then you only need to import it like below in your app.module.ts - import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

and then use it like below

@NgModule({
     ...
     imports : [BrowserModule,HttpClientModule,NgbModule.forRoot()],
     providers: [.... other services ..]
     })

NgbActiveModal is not required to be added in providers.

Update : You also need to import the HttpClientModule module in your spec file for unit testing. Testbed creates a test module for testing your component. As you have injected OrganisationsApiService in the constructor of the component, you need to add it to the providers array of the testbed module like below .

here is the code for the spec file of CleanupComponent -

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import { CleanupComponent } from './cleanup.component';
import { OrganisationsApiService } from 'src/app/api/organisations/organisations-api.service';

describe('CleanupComponent', () => {
  let component: CleanupComponent;
  let fixture: ComponentFixture<CleanupComponent>;

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

  beforeEach(() => {
    fixture = TestBed.createComponent(CleanupComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Similarly you need to do the change for the other spec file for ModalWipedAll

like image 72
Niladri Avatar answered Sep 27 '22 22:09

Niladri


If you are using unit testing by ng test using Jasmine and Karma, then you may need to import HttpClientTestingModule in the spec file.

like image 39
Sunny Avatar answered Sep 27 '22 20:09

Sunny