Skip to content

fix(effects): use switchMap for list-fetch effects to prevent stale data#2369

Open
alubbock wants to merge 2 commits into
SciCatProject:masterfrom
alubbock:fix/perf-003-switchmap-list-effects
Open

fix(effects): use switchMap for list-fetch effects to prevent stale data#2369
alubbock wants to merge 2 commits into
SciCatProject:masterfrom
alubbock:fix/perf-003-switchmap-list-effects

Conversation

@alubbock
Copy link
Copy Markdown
Member

@alubbock alubbock commented May 8, 2026

Description

Replace mergeMap with switchMap in the four list-fetching NgRx effects that handle user-driven queries (filter changes, sort, pagination).

Motivation

With mergeMap, rapidly changing filters or sort order leaves multiple concurrent HTTP requests in flight simultaneously. Responses can arrive out of order and overwrite newer store state with stale results. For example, a slow first request completing after a faster second one would silently replace the correct data with stale results.

switchMap cancels the previous in-flight request when a new action arrives, so only the response to the latest query is ever committed to the store. Angular's HttpClient supports cancellation, so the superseded request is also dropped on the network side.

Fixes:

  • fetchDatasets$ in datasets.effects.ts
  • fetchFacetCounts$ in datasets.effects.ts
  • fetchMetadataKeys$ in datasets.effects.ts
  • fetchProposalDatasets$ in proposals.effects.ts

The inner mergeMap calls that dispatch multiple actions from a single HTTP response are intentionally unchanged.

Changes:

  • Four one-word operator changes across datasets.effects.ts and proposals.effects.ts
  • Four marble-based regression tests added (one per effect) using the "-a-b" / "--a|" pattern: two rapid actions with a delayed response, asserting only the second response reaches the store

Tests included

  • Included for each change/fix?
  • Passing? (Merge will not be approved unless this is checked)

Summary by Sourcery

Use cancellable NgRx effects for list-fetching actions to avoid stale data when queries change rapidly.

Bug Fixes:

  • Prevent outdated dataset, facet count, metadata key, and proposal dataset responses from overwriting newer store state by switching list-fetch effects to use cancellable operators.

Tests:

  • Add marble tests verifying that a second rapid fetch action cancels the in-flight request and only the latest response updates the store for each affected effect.

alubbock added 2 commits May 8, 2026 22:46
Replace mergeMap with switchMap in fetchDatasets$, fetchFacetCounts$,
fetchMetadataKeys$ (datasets.effects) and fetchProposalDatasets$
(proposals.effects).

With mergeMap, rapidly changing filters or sort order left multiple
concurrent requests in flight. Responses arriving out of order could
overwrite newer store state with stale results. switchMap cancels the
previous in-flight HTTP request when a new action arrives, so only the
latest query's response is ever committed to the store.

The inner mergeMap calls used to dispatch multiple actions from a single
HTTP response are intentionally unchanged.
@alubbock alubbock requested a review from a team as a code owner May 8, 2026 21:55
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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.

1 participant