Angular 16使用抽象类报错:TypeError: this.httpService.get不是函数
问题描述
在Angular 16中通过抽象类AbstractHttpService进行依赖注入时,出现如下错误:
Error: Uncaught (in promise): TypeError: this.httpService.get is not a function
直接注入实现类HttpService时功能正常,说明问题出在抽象类的DI配置逻辑上。
核心原因
Angular的依赖注入系统无法直接实例化抽象类,必须明确告知容器:当请求AbstractHttpService类型的依赖时,应该提供哪个具体实现类的实例。同时,抽象类本身不需要添加@Injectable装饰器。
解决步骤
移除抽象类的@Injectable装饰器
修改Services/http.abstract_service.ts,删除不必要的@Injectable配置:import { Observable } from 'rxjs'; export abstract class AbstractHttpService { public abstract get(url: string): Observable<any>; }配置抽象类与实现类的DI映射
在根模块(如AppModule)的providers数组中添加映射规则,告诉DI容器用HttpService实现AbstractHttpService:import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from '@angular/common/http'; import { AbstractHttpService } from './Services/http.abstract_service'; import { HttpService } from './Services/http.service'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, HttpClientModule], providers: [ { provide: AbstractHttpService, useClass: HttpService } ], bootstrap: [AppComponent] }) export class AppModule { }若使用独立组件(Standalone Components),可在
bootstrapApplication时全局配置:bootstrapApplication(AppComponent, { providers: [ { provide: AbstractHttpService, useClass: HttpService } ] });修复HttpService中的潜在问题
原HttpService的get方法中else分支未返回有效值,可能导致订阅异常,建议补充返回逻辑:get(url: string): Observable<any> { return this.http.get(url, { observe: 'response' }).pipe( map((res: any) => { let responseBody = res?.body; let result: HttpResponse; if (res) { result = { status: res.status.toString(), data: responseBody.data, success: responseBody.success, message: responseBody.message }; } else { console.log(`Error! HttpStatus: ${res?.status || 'unknown'}`); // 返回错误状态的响应对象 result = { status: res?.status.toString() || '500', data: null, success: 'false', message: '请求无响应' }; } return result; }) ); }
验证
完成上述配置后,调用DataService.getMyData()时,DI容器会正确注入HttpService实例,this.httpService.get方法即可正常执行。
内容的提问来源于stack exchange,提问作者Scottish Smile

