Skip to content

fix(angular-virtual): wrap onChange signal write in untracked to prevent NG0600 - #1295

Open
okxint wants to merge 1 commit into
TanStack:mainfrom
okxint:fix/angular-virtualizer-untracked-onchange
Open

okxint wants to merge 1 commit into
TanStack:mainfrom
okxint:fix/angular-virtualizer-untracked-onchange

Conversation

@okxint

@okxint okxint commented Oct 1, 2026 •

Copy link
Copy Markdown

Fixes #1096.

onChange calls reactiveVirtualizer.set(instance) to update a linkedSignal. When a template reads virtualizer.getVirtualItems() inside a computed or effect, Angular evaluates the computed eagerly on change detection. The set() inside onChange then fires within that evaluation context, triggering NG0600: Writing to signals is not allowed in a computed or an effect.

untracked is already imported at line 11. Wrapping the set() call in untracked() escapes the reactive context and silences the error without changing behavior — the signal still updates and downstream computeds re-evaluate on the next tick.

// before
onChange: (instance, sync) => {
  reactiveVirtualizer.set(instance)
  ...
}

// after
onChange: (instance, sync) => {
  untracked(() => reactiveVirtualizer.set(instance))
  ...
}

Summary by CodeRabbit

  • Bug Fixes
    • Virtualizer change notifications no longer track surrounding reactive reads when updating reactive state, helping prevent unintended reactive updates. DOM-flush scheduling and user-provided change callbacks continue to work as before.

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: d800bb71-d4d2-4a0b-b37c-748206bad494

📥 Commits

Reviewing files that changed from the base of the PR and between 78371e8 and 562621f.

📒 Files selected for processing (1)
  • packages/angular-virtual/src/index.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The Angular virtualizer now updates reactiveVirtualizer inside untracked when its onChange callback runs. Optional DOM-flush scheduling and the user callback remain unchanged.

Changes

Angular signal update

Layer / File(s) Summary
Untracked virtualizer signal update
packages/angular-virtual/src/index.ts
The onChange callback wraps the reactiveVirtualizer.set(instance) update in untracked. The remaining callback behavior is unchanged.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~5 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 56262

The update avoids the reported Angular error while continuing to notify signal consumers. No actionable merge risk remains.

Architecture Summary

Architecture risk: 🔵 Low · up to 56262

The change affects 1 system.

Changed systems: packages/angular-virtual

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — packages/angular-virtual (library) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in packages/angular-virtual/src/index.ts: The reactiveVirtualizer.set(instance) update is now wrapped in untracked; the remaining onChange behavior is unchanged.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Angular virtualizer fix, the affected callback, and the purpose of preventing NG0600. It is concise and directly related to the main change.
Description check ✅ Passed The description clearly explains the change, motivation, affected signal behavior, and expected outcome. It omits the template’s Checklist and Release Impact sections, but it provides the core informa…
Linked Issues check ✅ Passed Issue #1096 requires Angular code to prevent NG0600 when getVirtualItems() evaluation triggers onChange. In packages/angular-virtual/src/index.ts, onChange now calls `untracked(() => reactiveV…
Out of Scope Changes check ✅ Passed The reviewed change is limited to the reactiveVirtualizer.set(instance) call in Angular virtualizer onChange. The change directly addresses issue #1096 and does not show unrelated behavior or file…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Angular Runtime NG0600: Writing to signals is not allowed introduced by (1085)

1 participant