錯誤百科

inject() 必須在注入上下文中呼叫

當你嘗試在允許的注入上下文之外使用 inject 函式時,就會看到這個錯誤。注入上下文在類別建立與初始化期間可以使用,搭配 runInInjectionContext 使用的函式也可以使用。

實務上,inject() 可以在建構函式、建構函式參數以及欄位初始化器中呼叫:

@Service()
export class Car {
  radio: Radio | undefined;

  // OK: field initializer
  spareTyre = inject(Tyre);

  constructor() {
    // OK: constructor body
    this.radio = inject(Radio);
  }
}

從 provider 的 factory 中呼叫 inject 也是合法的:

providers: [
  {
    provide: Car,
    useFactory: () => {
      // OK: a class factory
      const engine = inject(Engine);
      return new Car(engine);
    },
  },
];

在類別建立之外、或在 runInInjectionContext 之外呼叫 inject 函式,就會導致錯誤。最值得注意的是,類別實例建立完成之後,禁止在方法(包括生命週期鉤子)中呼叫 inject():

@Component({ ... })
export class Car {
  ngOnInit() {
    // ERROR: too late, the component instance was already created
    const engine = inject(Engine);
    engine.start();
  }
}

如何除錯

從錯誤的堆疊追蹤往回追蹤,找出那個不被允許的 inject() 呼叫位於何處。

要修復這個錯誤,請把 inject 的呼叫移至允許的位置(通常是類別建構函式或欄位初始化器)。

NOTE: 如果你是在測試上下文中執行,TestBed.runInInjectionContext 會讓 inject() 能夠成功執行。

TestBed.runInInjectionContext(() => {
  // ...
});