Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
inject() retrieves a dependency from the injector that is active at the moment the call runs, and it works only inside an injection context. In practice that means class constructors, field initializers on Angular-managed classes, provider factory functions, and functions that Angular itself runs in that context. If you call it from an ordinary method or a lifecycle hook such as ngOnInit, Angular raises error NG0203. In most cases the fix is to move the call up into a field initializer or the constructor. The sections below cover the valid locations, the optional-injection typing, the workarounds for code outside a context, and the official migration from constructor parameters.
What inject() does
Angular’s API reference describes the function in one line: “Injects a token from the currently active injector.” (Angular inject API reference). The “currently active injector” is the one Angular has chosen for the code that is running, which is why the function depends on timing and location rather than on an import alone. Importing inject from @angular/core is necessary but not sufficient; the call also has to happen while an injection context exists.
Where inject() is allowed
Angular’s injection context guide lists the situations where the call succeeds (Angular injection context guide). In summary, a call is valid when it runs in:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →- the constructor of a class that Angular instantiates through its dependency injection system;
- a field initializer of such a class, which runs as part of construction;
- a provider factory function or an
InjectionTokenfactory function; - any function called while an injection context is active. Router guard functions are a common example of APIs that execute inside one.
Where inject() fails
An instance method or lifecycle hook runs after Angular has already created the instance, so no injection context is active at that point. The call raises NG0203 (Angular NG0203 error reference). The following pattern fails:
#1 Best Overall
export class CartComponent implements OnInit {
ngOnInit() {
const cart = inject(CartService); // NG0203
cart.load();
}
}
Moving the lookup into a field initializer makes it valid, because field initializers run during construction:
export class CartComponent implements OnInit {
private cart = inject(CartService);
ngOnInit() {
this.cart.load();
}
}
Return values and options
The function is overloaded for two kinds of token. For a provider token, a standard injection returns the resolved value. Passing the optional flag changes the return type, because a missing provider then yields null rather than a value. For a host attribute token, the call returns a string when the attribute is present; its optional overload can return null. The options object corresponds to lookup strategies such as host, self, and skip-self behavior, as well as optional lookup (Angular inject API reference).
Rank #2
| Call form | Return type | When no value is found |
|---|---|---|
inject(TOKEN) (provider token) |
The resolved value of the token’s type | The optional-case null does not apply; the reference does not describe a null result for this form |
inject(TOKEN, {optional: true}) |
The resolved value, typed to include null |
null |
| Host attribute injection (standard) | string | Present only when the attribute exists on the host element |
| Host attribute injection (optional overload) | string or null |
null |
When you write examples or review code, make optionality explicit and keep the nullable type in the declaration. A field typed as the non-null service while the lookup can return null moves the failure to a later property access.
Running inject() outside a context
Sometimes a function that needs dependencies is called from code that has no injection context, such as a helper invoked from a plain callback. Angular’s guide describes runInInjectionContext for this case, which takes an injector, typically an EnvironmentInjector from the environment hierarchy outside the component tree (Angular EnvironmentInjector API reference). The procedure is:
Rank #3
- Obtain an injector that is available to the code, for example one passed in as a parameter or one injected into a class that is already constructed in a valid context.
- Wrap the dependency lookup in
runInInjectionContext(injector, () => ...), callinginject()inside the callback. - Keep the lookup synchronous. The context exists only while the callback is running, so do not schedule
inject()in a later callback or place it after anawait.
The EnvironmentInjector.runInContext method is deprecated, and Angular’s API points developers to the standalone runInInjectionContext function instead (Angular EnvironmentInjector API reference).
Diagnosing NG0203
NG0203 means that inject() ran outside an allowed injection context. Work through these checks in order:
Rank #4
- Read the stack trace to find the line that called
inject(), then identify which function or method contains it. - If that function is an instance method or lifecycle hook, move the lookup to a field initializer or the constructor.
- If the code is a helper that must run later, pass an injector into it and use
runInInjectionContextaround the synchronous lookup. - If the call is in a test that needs a DI context, use
TestBed.runInInjectionContextrather than calling the function directly.
The official error page for NG0203 is the reference for the exact condition (Angular NG0203 error reference).
Recommended Free Tools
Migrating constructor injection
Angular provides a schematic that converts eligible constructor parameters to inject() calls. Run it with:
ng generate @angular/core:inject
The schematic replaces eligible constructor parameters with field declarations such as private service = inject(MyService), and optional parameters with calls such as inject(DI_TOKEN, {optional: true}) (Angular inject migration guide). Review the diff before committing, since the schematic only rewrites parameters it judges eligible.
migrateAbstractClasses
This option is disabled by default. Angular cannot verify that constructor parameters of abstract classes are injectable, so migrating them can introduce breakage. Leave abstract classes on constructor injection unless you have checked each parameter manually.
backwardsCompatibleConstructors
Some decorated class hierarchies depend on a constructor signature that subclasses still call. This option keeps that signature so inheritance keeps working. The cost is extra generated code, and the migrated class is not as clean as a pure inject() version.
nonNullableOptional
Older code sometimes typed an @Optional() parameter without null. This option preserves that non-null type by adding a non-null assertion. Optional injection can return null, so the assertion can hide a real missing-value case. Enable it only when that behavior is intentional, and otherwise let the nullable type show up in the code so each use can be checked.
inject() in tests
Angular also exports a separate inject helper from @angular/core/testing. It injects dependencies into beforeEach() and it() blocks and is meant only for tests. Application code should import inject from @angular/core (Angular testing inject API reference). Keep the two imports distinct so that a test helper does not end up in production source.
Quick Recap
“
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

