首页 > 解决方案 > NullInjectorError:没有 HttpHandler 的提供者!尽管存在 HttpClient/HttpClientModule

问题描述

我是基于 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,
]})

清理组件.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: [AwsApiService,
              OrganisationsApiService,
              LabsApiService,
              UsersApiService,
              UserManagementDataService,
              ConfigDataService,
              ErrorDataService,
              DeploymentResponseDataService,
              ModalOptionsComponent,
              ModalConfigurationComponent,
              ModalUndeployLabComponent,
              ModalCreatedUserComponent,
              NgbActiveModal,
              HttpClientModule,
              HttpClient,


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

错误信息:

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)

我希望项目能够像在本地一样构建,而是得到 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();
  });
});

清理组件

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();
  });
});

标签: angularangular6

解决方案


有几个步骤可以实现这一点 -

  1. 在您的 app.module.ts 导入HttpClientModule中,如下所示

    从“@angular/common/http”导入 { HttpClientModule };

并使用它像下面的imports数组。@NgModule

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

HttpClientModule 应该在 BrowserModule 之后添加。这个顺序在imports数组中很重要。

  1. HttpClientModule从组件中删除所有的导入。如果您在根模块中导入它就足够了。

  2. 从app.module.ts 中HttpClientproviders数组中移除,它不是必需的。@NgModule您可以直接在组件的构造函数中注入 HttpClient 的实例,而无需将其添加到提供程序中。

  3. 如果你正在使用,ng-bootstrap那么你只需要在你的 app.module.ts 中像下面这样导入它 - import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

然后像下面一样使用它

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

NgbActiveModal不需要在提供程序中添加。

更新:您还需要HttpClientModule在规范文件中导入模块以进行单元测试。Testbed 创建一个测试模块来测试你的组件。由于您在组件的构造函数中注入了 OrganisationsApiService,因此您需要将其添加到providerstestbed 模块的数组中,如下所示。

这是规范文件的代码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();
  });
});

同样,您需要对其他规范文件进行更改ModalWipedAll


推荐阅读