Angular应用调用服务时触发NullInjectorError问题排查求助
Angular应用使用服务时出现NullInjectorError问题排查
在我的Angular应用中,尝试使用服务时触发了NullInjectorError错误。我修改过angular.json的默认配置,怀疑这是问题根源。以下是相关文件内容:
app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AngularEditorModule } from '@kolkov/angular-editor'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AdminCrudComponent } from './components/admin-crud/admin-crud.component'; import { FormInputComponent } from './components/form-input/form-input.component'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ AppComponent, AdminCrudComponent, FormInputComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule, AngularEditorModule, HttpClientModule, ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
admin.service.ts
import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { URLConfig } from '../config/url.config'; import { environment } from '../../environments/environment'; @Injectable({ providedIn: 'root' }) export class AdminService { constructor(private httpclient: HttpClient, private urlConfig: URLConfig) { } createItem(item: any) { const service = this.urlConfig.getConfig(environment.env); const url = service.myApi + 'items'; const headers = new HttpHeaders(); headers.append('Content-Type', 'multipart/form-data'); return this.httpclient.post(url, item, { headers: headers }); } }
angular.json
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "client": { "projectType": "application", "schematics": { "@schematics/angular:component": { "style": "scss" }, "@schematics/angular:application": { "strict": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/client", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "scss", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.scss", "node_modules/bootstrap/dist/css/bootstrap.min.css" ], "scripts": ["node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"] }, "configurations": { "prod": { "budgets": [ { "type": "initial", "maximumWarning": "500kb", "maximumError": "1mb" }, { "type": "anyComponentStyle", "maximumWarning": "2kb", "maximumError": "4kb" } ], "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "outputHashing": "all" }, "uat": { "budgets": [ { "type": "initial", "maximumWarning": "500kb", "maximumError": "1mb" }, { "type": "anyComponentStyle", "maximumWarning": "2kb", "maximumError": "4kb" } ], "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.uat.ts" } ], "outputHashing": "all" } }, "defaultConfiguration": "prod" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "prod": { "browserTarget": "client:build:prod" }, "uat": { "browserTarget": "client:build:uat" } }, "defaultConfiguration": "uat" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "client:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js", "inlineStyleLanguage": "scss", "assets": [ "src/favicon.ico", "src/assets" ], "styles": [ "src/styles.scss" ], "scripts": [] } } } } }, "defaultProject": "client" }
package.json
{ "name": "client", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "start:uat": "ng serve --configuration=uat", "start:prod": "ng serve --configuration=prod", "watch": "ng build --watch --configuration development", "test": "ng test" }, "private": true, "dependencies": { "@angular/animations": "~13.2.0", "@angular/common": "~13.2.0", "@angular/compiler": "~13.2.0", "@angular/core": "~13.2.0", "@angular/forms": "~13.2.0", "@angular/platform-browser": "~13.2.0", "@angular/platform-browser-dynamic": "~13.2.0", "@angular/router": "~13.2.0", "@kolkov/angular-editor": "^3.0.0-beta.0", "angular-font-awesome": "^3.1.2", "bootstrap": "^5.3.3", "ngx-editor": "^13.0.0", "rxjs": "~7.5.0", "tslib": "^2.3.0", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "~13.2.0", "@angular/cli": "~13.2.0", "@angular/compiler-cli": "~13.2.0", "@types/jasmine": "~3.10.0", "@types/node": "^12.11.1", "jasmine-core": "~4.0.0", "karma": "~6.3.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.1.0", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "~1.7.0", "typescript": "~4.5.2" } }
问题根源与解决方案
问题原因
NullInjectorError的触发和你修改的angular.json配置无关,真正原因是AdminService构造函数中注入的URLConfig没有在Angular依赖注入系统中注册。Angular无法找到这个类的实例,因此抛出注入错误。
解决办法
将URLConfig注册为服务
给URLConfig类添加@Injectable装饰器,指定providedIn: 'root',让Angular自动注册它为根级服务:import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class URLConfig { getConfig(env: string) { // 你的原有逻辑实现 } }若URLConfig不是服务则直接实例化
如果URLConfig只是普通工具类而非服务,不要通过构造函数注入,而是在AdminService中直接创建实例:constructor(private httpclient: HttpClient) { } createItem(item: any) { const urlConfig = new URLConfig(); const service = urlConfig.getConfig(environment.env); // 后续逻辑不变 }替代方案:直接在环境文件中配置API地址
对于多环境配置,Angular推荐直接在environment.ts、environment.uat.ts等文件中定义API地址,无需额外的URLConfig类:// environment.ts export const environment = { env: 'dev', myApi: 'http://dev-api.example.com/' }; // environment.uat.ts export const environment = { env: 'uat', myApi: 'http://uat-api.example.com/' };这样在
AdminService中可以直接使用,简化代码:createItem(item: any) { const url = environment.myApi + 'items'; // 后续逻辑不变 }
内容的提问来源于stack exchange,提问作者Prabhat Bhargav
相关产品推荐
相关产品推荐

