Skip to content

fix: detect array length drift so cleared arrays re-render#7651

Open
AKnassa wants to merge 1 commit into
microsoft:mainfrom
AKnassa:fix/7167-array-length-drift
Open

fix: detect array length drift so cleared arrays re-render#7651
AKnassa wants to merge 1 commit into
microsoft:mainfrom
AKnassa:fix/7167-array-length-drift

Conversation

@AKnassa

@AKnassa AKnassa commented Jul 13, 2026

Copy link
Copy Markdown

What this does

Makes myArray.length = 0 — the everyday way to empty an array in JavaScript — actually clear the list on screen.

Why

FAST notices array changes by wrapping the array's methods (push, splice, pop, and so on). Setting length is not a method call, so nothing noticed it. The array really was emptied, but repeat kept rendering the old items, and lengthOf kept reporting the old count.

The person who reported this put it plainly: "I cannot use FAST until this is resolved."

What changed

01-initial-state 02-before-bug 03-after-fixed 04-side-by-side
  • The array observer now remembers how long the array should be after the changes it knows about. When the real length disagrees, it emits a reset instead of change records that no longer describe reality, and the list re-renders from scratch.
  • The companion path in the declarative observer map handles a reset the same way.

This same drift check also covers the other silent cases — delete arr[i], writing past the end of the array, and the array methods that were never wrapped.

An honest limit

length cannot be intercepted directly (it is non-configurable, so it cannot be trapped without turning arrays into Proxies, which would be a much larger change). What this does is detect the drift and heal from it. So arr.length = 0 on its own, with no other tracked change afterwards, still does not notify — the array observer has nothing to wake it. In practice the clear is nearly always followed by tracked work, which is when the correction lands.

If maintainers would rather solve this properly with a Proxy-based reactive array, this PR is a stopgap and should be judged that way.

How to see it

Run the fast-element test suite. New tests in observation/arrays.pw.spec.ts set length = 0, push a new item, and assert a single reset arrives — where main produces change records describing an array that no longer exists.

The existing test that asserts array.splice(0, array.length, ...array) produces no change records is the sharpest guard here: the net length change is zero, so the drift check must not fire. It still passes.

Fixes #7167

`array.length = 0` is the common idiom for clearing an array, but the length
property cannot be trapped without a Proxy, so it recorded no splice and
`repeat` kept rendering the removed items.

The array observer now tracks the length it expects after the queued changes
and, when the real length disagrees, emits a reset instead of incremental
splices that no longer describe reality.

Fixes microsoft#7167
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@AKnassa AKnassa marked this pull request as ready for review July 14, 2026 02:24
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

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.

fix: observables not work as expected in repeat directive and change functions

1 participant