You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 06:40:25