NullInjectorError: 没有 HttpHandler 的提供者!尽管存在 HttpClient/HttpClientModule

Cal*_*tin 5 angular angular6

我是一个基于 Angular 的 UI 项目的新手,并使用 vscode 生成了两个新组件以用于该项目。但是,每当我将更改推送到 git(bitbucket) 时,我都会收到错误消息,并且在我的机器上构建项目时不存在这些错误。我需要在哪里提供 HttpClient/HttpClientModule 以便这些新组件可以使用 HttpHandler?

我已经在 app.module.ts 和新组件本身上为 HttpClientModule 和 HttpClient 添加了提供程序。

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,
]})
Run Code Online (Sandbox Code Playgroud)

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) {

   }
Run Code Online (Sandbox Code Playgroud)

app.module.ts 提供者

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


     { provide: HTTP_INTERCEPTORS,
      useClass: HttpRequestInterceptor,
      multi: true}
    ],   
Run Code Online (Sandbox Code Playgroud)

错误信息:

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)
Run Code Online (Sandbox Code Playgroud)

我希望该项目能够像在本地一样构建,而是得到 NullInjectorErrors

更新:component.spec.ts 文件 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();
  });
});
Run Code Online (Sandbox Code Playgroud)

清理组件

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

Nil*_*dri 12

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 ..]
 })
Run Code Online (Sandbox Code Playgroud)

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 ..]
     })
Run Code Online (Sandbox Code Playgroud)

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

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


小智 6

如果您使用 Jasmine 和 Karma 通过 ng test 进行单元测试,那么您可能需要在规范文件中导入 HttpClientTestingModule。

  • 如果有人在此处查看此答案的代码部分,请在您的 spec.ts 文件中 import { HttpClientTestingModule } from '@angular/common/http/testing'; beforeEach(() =&gt; { TestBed.configureTestingModule({ 导入: [HttpClientTestingModule], }); }); (2认同)