mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
docs: create a dedicated page for the NG0203 error (#46166)
Adds a dedicated error page for NG0203 (injection context). PR Close #46166
This commit is contained in:
committed by
Andrew Scott
parent
6b52f03f5f
commit
12b4ec3d85
@@ -0,0 +1,83 @@
|
||||
@name `inject()` must be called from an injection context
|
||||
@category runtime
|
||||
@shortDescription `inject()` must be called from an injection context (a constructor, a factory function or a field initializer)
|
||||
|
||||
@description
|
||||
You see this error when you try to use the `inject()` function outside of the allowed injection context. The injection context is available during the class creation and initialization.
|
||||
|
||||
In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a field initializer:
|
||||
|
||||
```typescript
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class Car {
|
||||
radio: Radio|undefined;
|
||||
|
||||
// OK: field initializer
|
||||
spareTyre = inject(Tyre);
|
||||
|
||||
// OK: constructor parameter
|
||||
constructor(readonly engine: Engine = inject(Engine)) {
|
||||
|
||||
// OK: constructor body
|
||||
this.radio = inject(Radio);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It is also legal to call `inject` from a provider's factory:
|
||||
|
||||
```typescript
|
||||
providers: [
|
||||
{provide: Car, useFactory: () => {
|
||||
// OK: a class factory
|
||||
const engine = inject(Engine);
|
||||
return new Car(engine);
|
||||
}}
|
||||
]
|
||||
```
|
||||
|
||||
The `inject()` calls might be wrapped in an intermediate function and will work correctly as long as a wrapper function is used in one of the allowed contexts:
|
||||
|
||||
```typescript
|
||||
function getAndLog<T>(token: ProviderToken<T>): T {
|
||||
const instance = inject(token);
|
||||
|
||||
console.log('Getting', token.toString());
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class Car {
|
||||
constructor(readonly engine: Engine = getAndLog(Engine)) {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Calls to the `inject()` function outside of the class creation context will result in error. Most notably, calls to `inject()` are disallowed after a class instance was created, in methods:
|
||||
|
||||
```typescript
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class Car {
|
||||
|
||||
start() {
|
||||
// ERROR: too late, the Car instance was already created and fully initialized
|
||||
const engine = inject(Engine);
|
||||
engine.start();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@debugging
|
||||
|
||||
Work backwards from the stack trace of the error to identify a place where the disallowed call to `inject()` is located.
|
||||
|
||||
To fix the error move the `inject()` call to an allowed place (usually a class constructor or a field initializer).
|
||||
|
||||
<!-- links -->
|
||||
|
||||
<!-- external links -->
|
||||
|
||||
<!-- end links -->
|
||||
|
||||
@reviewed 2022-05-27
|
||||
Reference in New Issue
Block a user