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:
Pawel Kozlowski
2022-05-27 13:52:34 +02:00
committed by Andrew Scott
parent 6b52f03f5f
commit 12b4ec3d85
3 changed files with 85 additions and 2 deletions
+83
View File
@@ -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