Question presented to candidate:
"You inject ChangeDetectorRef into a component. What can it do, when would you reach for markForCheck() versus detectChanges(), and why do you need it less in a signals-based Angular 22 app?"
What a strong answer should cover:
ChangeDetectorRefis the handle to one component's view in the change detection tree; in v22 its public API is exactly four methods:markForCheck,detectChanges,detach,reattach.markForCheck()flags the view and its ancestors and lets the scheduler run later (asynchronous);detectChanges()checks this view and its children right now (synchronous), whether or not anything is flagged.detach()removes the view from the tree so normal runs skip it even when marked;detectChanges()still works on a detached view, which enables manual, throttled rendering.- Under the v22 defaults (OnPush, zoneless) a plain field changed in async code needs one of these; a signal needs neither, and
AsyncPipecallsmarkForCheck()internally. checkNoChanges()was removed from the publicChangeDetectorRefAPI in v22; tests usefixture.detectChanges()instead.
Clarifying questions expected:
- "Is the state in signals already, or is this legacy code with plain fields and Observables?"
- "Is the goal to fix a stale view, or to deliberately throttle rendering of a hot component?"
Code / implementation expected: Yes β show markForCheck() and detectChanges() updating a stale OnPush view, and detach() blocking normal updates.