Angular 17函数式守卫报错:NullInjectorError找不到_UserService提供者
问题:Angular 17函数式权限守卫注入UserService报NullInjectorError
报错信息
ERROR NullInjectorError: NullInjectorError: No provider for _UserService! at NullInjector.get (core.mjs:5626:27) at R3Injector.get (core.mjs:6069:33) at R3Injector.get (core.mjs:6069:33) at injectInjectorOnly (core.mjs:911:40) at ɵɵinject (core.mjs:917:42) at inject (core.mjs:1001:12) at authGuard (auth.guard.ts:6:23) at router.mjs:3323:134 at runInInjectionContext (core.mjs:6366:16) at router.mjs:3323:89
相关代码
authGuard.ts
import {CanActivateFn, Router} from '@angular/router'; import {inject} from "@angular/core"; import {UserService} from "../users/user.service"; export const authGuard: CanActivateFn = (route, state) => { const userService = inject(UserService); const router = inject(Router); if (!userService.is_authenticated()) { router.navigate(['login', state.url]); return false; } return true; };
UserService.ts
import {Injectable} from '@angular/core'; import { JwtHelperService } from '@auth0/angular-jwt'; import {HttpClient} from '@angular/common/http'; @Injectable() export class UserService { private usersUrl = '/users/'; constructor(private http: HttpClient, private jwtHelper: JwtHelperService) { } ... public is_authenticated(): boolean { const token = localStorage.getItem('token'); // Check whether the token is expired and return // true or false return !this.jwtHelper.isTokenExpired(token); } }
用户疑问
已将旧Angular项目迁移至Angular 17,类式权限守卫改为函数式后出现上述报错。根据文档理解,使用inject()即可获取依赖,无需额外配置UserService的提供者,请问哪里操作错误?
解答
- 核心问题:UserService的@Injectable装饰器未指定提供者范围。Angular允许在函数式守卫中用
inject()获取依赖,但前提是服务本身已被正确注册为Angular的依赖提供者。 - 你的
UserService仅使用了空的@Injectable(),没有设置providedIn元数据,Angular无法自动识别并创建该服务的实例,导致注入失败。 - 修复方案:
修改UserService的@Injectable装饰器,添加providedIn: 'root',将服务注册到根注入器:@Injectable({ providedIn: 'root' }) export class UserService { // 原有代码保持不变 } - 替代方案:如果需要将服务限定在特定模块中,也可以在对应模块的
providers数组中注册UserService,但推荐使用providedIn: 'root',它支持Angular的树摇优化,减少打包体积。 - 额外检查:确保
JwtHelperService已正确注册,@auth0/angular-jwt通常需要在模块中导入JwtModule并配置,若该服务本身是providedIn: 'root'则无需额外操作。
内容的提问来源于stack exchange,提问作者Silko
相关产品推荐
相关产品推荐

