Angular › Change Detection

Why does mutating an array or object directly sometimes fail to trigger a component update when using OnPush?

Intermediate

Answer

With OnPush, Angular only checks whether an input's reference has changed, not whether its internal contents have changed. Directly mutating an existing array or object keeps the same reference, so Angular does not detect anything different, even though the actual data inside has changed.
// Wrong with OnPush, mutates the existing array directly, Angular does not notice the change
this.items.push(newItem);

// Correct, creates a brand new array so Angular detects the change
this.items = [...this.items, newItem];
Real-world example A to do list component using OnPush that would not visually update after adding a new item is fixed by replacing a direct array mutation with a fresh array created using the spread operator, letting Angular correctly detect the change.

Common follow-ups: Why does this same problem not happen with the Default change detection strategy?;How do signals help avoid this specific class of bug entirely?