angular/aio/content/errors/NG0203.md
Pawel Kozlowski 12b4ec3d85 docs: create a dedicated page for the NG0203 error (#46166)
Adds a dedicated error page for NG0203 (injection context).

PR Close #46166
2022-05-27 10:15:55 -07:00

2.2 KiB

@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:

@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:

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:

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:

@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).

@reviewed 2022-05-27