Question presented to candidate:
"A developer moved a toSignal() call from a field into a click handler and the app now throws NG0203. Explain what an injection context is, what runInInjectionContext does, and when you would reach for it instead of restructuring the code."
What a strong answer should cover:
- An injection context is the synchronous window in which
inject()knows which injector to use: constructors, field initialisers, factory functions (useFactory,providedInfactories), functional guards, resolvers and interceptors. inject(),toSignal(),toObservable(),effect(),takeUntilDestroyed()and custominjectX()helpers all require one; outside it they throw NG0203.runInInjectionContext(injector, fn)runsfnsynchronously as if inside that injector's context; it does not survive asetTimeoutor anawaitinsidefn.- The injector you pass decides lifetime: a component's
Injectorcleans up with the component; anEnvironmentInjector(root) lives with the app. - Prefer alternatives first: move the call to a field, or pass
{ injector }/ aDestroyRefto APIs that accept it. UserunInInjectionContextfor library code, dynamic setup, and tests (TestBed.runInInjectionContext). assertInInjectionContext(fn)to give your own helpers the same clear error.
Clarifying questions expected:
- "Does the work really have to start in the handler, or could it be created up front and triggered later?"
- "Should what it creates live as long as the component, or as long as the app?"
Code / implementation expected: Yes β an injectX() helper that fails from a click handler with NG0203 and works through runInInjectionContext.