effect-in-injection-context
September 2, 2026 · View on GitHub
Checks that effect() is called inside an injection context, or that an explicit Injector is provided in the second argument, to avoid the NG0203 runtime error.
Documentation
Configuration
- in the
recommendedpreset - in the
injectionContextpreset
{
rules: {
'eslint-plugin-angular-modern/effect-in-injection-context': 'error'
}
}
Tip
See the README for the global and presets configuration.
❌ Invalid
All the invalid cases are without an injector. See the valid cases below to see an example of how to provide an explicit Injector.
- in lifecycle methods, notably
ngOnInit
@Component()
export class ProductPage implements OnInit {
ngOnInit(): void {
effect(() => {});
}
}
- in any methods other than the constructor
@Component({
template: `<form (submit)="save()"></form>`
})
export class ProductEditPage {
save(): void {
effect(() => {});
}
}
- in callbacks
@Component()
export class ProductPage {
readonly #dataObservable = someObservable.pipe(
tap(() => {
effect(() => {});
}),
);
}
Note
The rule reports both on asynchronous and synchronous callbacks, see the known limitation documentation.
- after awaiting (which is equivalent to be in a
.then()callback)
@Component()
export class ProductEditPage {
async save(): Promise<void> {
await somePromise();
effect(() => {});
}
}
- in non-Angular classes
export class Product {
constructor() {
effect(() => {});
}
}
- in standalone functions
function someFunction(): void {
effect(() => {});
}
✅ Valid
- in constructors of components, directives, pipes and injectables/services
@Component()
export class ProductsPage {
constructor() {
effect(() => {});
}
}
- in property initializers of components, directives, pipes and injectables/services
@Component()
export class ProductPage {
readonly #someEffect = effect(() => {});
}
- when providing an explicit
Injector
@Component()
export class ProductPage implements OnInit {
readonly #injector = inject(Injector);
ngOnInit(): void {
effect(() => {}, { injector: this.#injector });
}
}
Note
Prefer a literal object as in this example. If the second argument is a variable, the lint rule will not check if injector is actually present, see the known limitation documentation.
- in explicit injection context
@Injectable({ providedIn: 'root' })
export class MyService {
readonly #environmentInjector = inject(EnvironmentInjector);
someMethod() {
runInInjectionContext(this.#environmentInjector, () => {
effect(() => {});
});
}
}
Note
The rule only detects runInInjectionContext() or TestBed.runInInjectionContext() in the current function, see the known limitation documentation.
- when asserted
function customOperator(injector: Injector) {
if (!injector) {
assertInInjectionContext(customOperator);
}
effect(() => {}, injector ? { injector } : undefined);
}