Skip to content

fix(angular-query): hold a pending task while a query subscription fetches - #11178

Open
yogesh968 wants to merge 1 commit into
TanStack:mainfrom
yogesh968:fix/angular-query-pending-task-timing
Open

fix(angular-query): hold a pending task while a query subscription fetches#11178
yogesh968 wants to merge 1 commit into
TanStack:mainfrom
yogesh968:fix/angular-query-pending-task-timing

Conversation

@yogesh968

@yogesh968 yogesh968 commented Aug 13, 2026

Copy link
Copy Markdown

Fixes #9981
Fixes #9910
Fixes #10046

The problem

createBaseQuery registers the Angular pending task from inside the observer subscription callback:

observer.subscribe(
  notifyManager.batchCalls((state) => {
    ngZone.run(() => {
      if (state.fetchStatus === 'fetching' && !pendingTaskRef) {
        pendingTaskRef = pendingTasks.add()
      }
      ...

Subscribing is what starts the fetch, but the callback is batched through the notify manager, so it runs in a later task than the fetch it reports. In between there is no pending task, the application counts as stable, and whenStable() resolves while the query is still loading.

That is what the three linked issues run into. In a TestBed test the usual fixture.detectChanges() followed by await fixture.whenStable() returns with the query still pending, data() still undefined, and any effect() reading isSuccess() never seeing true. The workaround people have landed on is an arbitrary setTimeout(0) before whenStable(), which #10046 describes.

The change

After subscribing, take the pending task straight away if the observer is already fetching. The release path is unchanged, so the task is still handed back on the first notification that reports fetchStatus: 'idle' and on cleanup.

Tests

Added a test to pending-tasks.test.ts that mounts a component the way the issues describe, with a template reading isSuccess() and an effect() observing it, and asserts on the state after fixture.whenStable(). It fails on main and passes here.

Two existing tests in inject-query.test.ts awaited whenStable() without letting the batched notification run and only passed because of this gap. They now advance the timers while waiting, which is the pattern the rest of pending-tasks.test.ts already uses.

Whole @tanstack/angular-query-experimental suite is green: 219 tests.

Summary by CodeRabbit

  • Bug Fixes
    • Angular applications now correctly remain unstable while a query is actively fetching.
    • whenStable() waits for asynchronous query loading to finish, including batched or delayed notifications.
    • Improved reliability for components that depend on query results during initialization.
  • Tests
    • Added coverage for asynchronous query completion and Angular stability behavior.
    • Updated timing-sensitive tests to ensure pending tasks are released correctly after fetching completes.

…tches

The pending task that keeps the application unstable was only registered
from inside the observer subscription callback. That callback is batched
through the notify manager, so it runs in a later task than the fetch it
reports. Between subscribing and that first notification the application
looks stable, which lets 'ApplicationRef.whenStable()' and
'fixture.whenStable()' resolve while the query is still loading.

Register the task right after subscribing when the observer is already
fetching, so the window is covered.

Two existing tests awaited 'whenStable()' without letting the batched
notification run, and only passed because of this gap. They now advance
the timers while waiting, matching the other pending task tests.
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 92551743-f3f4-4834-9b94-08cbf5c81c42

📥 Commits

Reviewing files that changed from the base of the PR and between 159982c and e1979e9.

📒 Files selected for processing (4)
  • .changeset/afraid-plums-shave.md
  • packages/angular-query-experimental/src/__tests__/inject-query.test.ts
  • packages/angular-query-experimental/src/__tests__/pending-tasks.test.ts
  • packages/angular-query-experimental/src/create-base-query.ts

📝 Walkthrough

Walkthrough

Angular query integration now registers pending tasks when fetching starts, including cases where observer notifications are batched. Tests cover timer processing, Angular stability, and effect observation. A patch changeset documents the behavior.

Changes

Angular pending-task flow

Layer / File(s) Summary
Register pending tasks for active fetches
packages/angular-query-experimental/src/create-base-query.ts
After observer subscription, active fetches register a pending task when no task exists.
Validate stability and effect timing
packages/angular-query-experimental/src/__tests__/inject-query.test.ts, packages/angular-query-experimental/src/__tests__/pending-tasks.test.ts, .changeset/afraid-plums-shave.md
Tests process batched notifications before awaiting stability and verify asynchronous completion through an Angular effect. The changeset documents the patch release.

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

Mergeability Score: ⚪ Minimal · up to e1979

The change keeps Angular pending-task tracking active during query startup and adds focused regression coverage; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers: sukvvon

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main Angular query pending-task fix.
Description check ✅ Passed The description explains the problem, implementation, regression tests, linked issues, and suite result, despite not using the template headings.
Linked Issues check ✅ Passed The implementation directly addresses the three linked issues by registering pending tasks before batched notifications and adding matching regression coverage.
Out of Scope Changes check ✅ Passed All changes are limited to the Angular query fix, related tests, and its required release changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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.

Weird bug with Angular unit tests isSuccess() not triggering effect() during testing Reading out query signals in template causes test failure

2 participants