Skip to content
5 changes: 5 additions & 0 deletions .changeset/angular-ssr-pending-task-coverage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/angular-query-experimental': patch
---

Keep the SSR pending task registered from fetch start until the query result is applied to the result signal. Previously the task was registered and released inside the subscriber callback: registration waited for the first notifyManager delivery turn (`setTimeout(0)`), and release ran one statement before the result signal write. With zoneless change detection, `ApplicationRef.whenStable()` could resolve in either gap, so Angular SSR serialized HTML rendered from stale optimistic state even though the fetch had completed. Fetches started elsewhere, such as by `invalidateQueries()`, are now covered as well.
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,10 @@ describe('injectQuery', () => {
// Synchronize pending effects
TestBed.tick()

// The in-flight fetch now holds a pending task, so stability requires the
// notification turn and the change detection it schedules to run first
await vi.advanceTimersByTimeAsync(0)
TestBed.tick()
const stablePromise = app.whenStable()
await stablePromise

Expand Down Expand Up @@ -653,6 +657,10 @@ describe('injectQuery', () => {
enabledSignal.set(true)
TestBed.tick()

// The in-flight fetch now holds a pending task, so stability requires the
// notification turn and the change detection it schedules to run first
await vi.advanceTimersByTimeAsync(0)
TestBed.tick()
await app.whenStable()
expect(query.status()).toBe('success')
expect(query.data()).toBe('sync-data-1')
Expand All @@ -677,6 +685,10 @@ describe('injectQuery', () => {
// Synchronize pending effects
TestBed.tick()

// The in-flight fetch now holds a pending task, so stability requires the
// notification turn and the change detection it schedules to run first
await vi.advanceTimersByTimeAsync(0)
TestBed.tick()
await app.whenStable()
expect(query.status()).toBe('success')
expect(query.data()).toBe('sync-data-1')
Expand Down
Loading