All quizzesHard
Standalone & Tokens — Series 3
Preview — 3 of 10 questions
Beyond forwardRef() (which only helps with declaration order, not a genuine mutual runtime dependency), what's the practical way to actually break this cycle?
javascript
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private orders: OrderService) {}
}
@Injectable({ providedIn: 'root' })
export class OrderService {
constructor(private users: UserService) {} // throws: Circular dependency
}AAdd @Optional() to both constructors; Angular resolves cycles automatically once both sides are optional
BSwap both services to providedIn: 'platform', which uses a different resolution algorithm that tolerates cycles
CHave one side stop asking for the other in its constructor, and instead inject the Injector (or use a lazily-called inject() inside a method, not a field initializer) to fetch the dependency only when actually needed, at call time rather than construction time — deferring the lookup until both services already fully exist breaks the "each needs the other to finish constructing" deadlock
DMerge the two services into one class; Angular has no other way to resolve a true cycle
Why pass { injector: this.injector } explicitly here, instead of relying on effect()'s default behavior?
javascript
export class WidgetHost {
constructor(private injector: Injector) {}
attach() {
effect(() => console.log(this.count()), { injector: this.injector });
}
}Aattach() is called later, outside the constructor's automatically-active injection context, so effect() has no ambient context to infer where it belongs; passing { injector: this.injector } explicitly supplies the injector to associate the effect with (for its lifetime and cleanup), which is the same problem runInInjectionContext() solves, just expressed as an option on effect() itself instead of a wrapping call
BIt has no effect; injector is ignored unless manualCleanup: true is also set
CThis is required syntax for every effect() call, regardless of where it's created
DIt only affects which zone the effect's callback runs in
Is calling onDestroy() twice on the same DestroyRef valid?
javascript
export function useInterval(fn: () => void, ms: number) {
const destroyRef = inject(DestroyRef);
const id = setInterval(fn, ms);
destroyRef.onDestroy(() => clearInterval(id));
destroyRef.onDestroy(() => console.log('interval cleaned up'));
}ANo — only the most recently registered callback actually runs; the first is silently discarded
BNo — this throws, since a DestroyRef only supports one registered callback at a time
CYes — DestroyRef.onDestroy() can be called any number of times, and every registered callback runs (order of registration) when the associated context is destroyed. There's no single-callback limitation; independent pieces of cleanup logic can each register their own callback separately
DYes, but only the second call actually takes effect if both are registered synchronously
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.