fix(dev-tools): restore Query Tool's persisted query + clear FileAsset example warnings (#36692) - #37869
Merged
Conversation
…t example warnings (#36692) QA found the Query Tool losing its query on every return to the portlet, while ES Search and Velocity Playground kept theirs. The store composes `withPersistedQuery`, which restores the last query in its own `onInit` — but that runs before the component's `ngOnInit`, which unconditionally wrote the `q` URL param over it. Navigating in from the menu carries no `q`, so the restored query was immediately replaced by ''. Query Tool is the only one of the three dev tools that reads URL params, which is why only it regressed. The param is now applied only when the URL actually carries `q` (`has`, not a truthiness check, so a shared `?q=` still clears the editor rather than silently resurrecting the previous query). Deep links keep winning over the restored value and still auto-run; a restored query is left unexecuted, as in the sibling tools. Also fixes the second item QA raised: the Velocity Playground "pull files" example referenced `$f.fileSize`, which is not a contentlet property — it resolved to null on every file, so the example ran with five NULL_METHOD_RESULT warnings and printed the literal `$f.fileSize`. Size is a metadata-backed getter on FileAsset, reachable through the `fileAsset` binary field (`$f.fileAsset.fileSize`); `fileName` and `mimeType` do resolve on the contentlet, which is what made the mistake easy to miss. The other three examples were audited and resolve cleanly. Tests: a new real-store describe in the page spec (every other describe mocks the store, so the onInit ordering was invisible to them) covering restore-on-reopen, deep-link precedence, and that the stored entry is never erased; plus a guard on the example catalog. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 of 10 tasks
hmoreras
reviewed
Oct 2, 2026
hmoreras
previously approved these changes
Oct 2, 2026
…istence specs Review feedback from @hmoreras on #37869: the "no debounced erase" test passes with the ngOnInit guard reverted, so it does not guard the fix — and the comments on it and on the sibling L209 test asserted the opposite. Both claims verified before changing anything. Reverting the guard locally fails exactly two tests (restore-on-reopen and the setQuery contract); the erase test stays green. And fake timers DO drive this debounce — `flushEffects()` first, so the rxMethod effect creates the timer, then `advanceTimersByTime`, as with-persisted-query.feature.spec.ts already does. The earlier comment blaming zone.js was wrong; the missing piece was flushEffects, not the clock. - L209 comment: drop the false claim that the stray '' deletes the stored entry. `skip(1)` absorbs it; the damage is confined to the editor the user sees. - Kept the erase test but renamed and reframed it as what it is: an invariant guard that reopening never destroys the saved query, explicitly flagged as NOT a regression test for this fix. `skip(1)` is the only thing between a stray write-on-init and silent data loss, so it is worth pinning on its own. - Switched it to fake timers, dropping a 400 ms real sleep from the suite. Confirmed non-vacuous with a throwaway probe: typing a value and advancing the clock does land it in localStorage, so a real erase would be observed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
hmoreras
approved these changes
Oct 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #36692 — addresses both items from @hmoreras' QA round on the merged #36781.
1. Query Tool did not persist the query (the QA blocker)
DotQueryToolStorecomposes the sharedwithPersistedQuery()feature correctly and did restore the last query — but the feature'sonInitruns when the store is constructed, i.e. before the component'sngOnInit, which then unconditionally wrote theqURL param over it:Arriving from the menu carries no
q, so the restored value was replaced by''a tick after it was restored. Query Tool is the only one of the three dev tools that reads URL params — which is exactly why ES Search and Velocity Playground kept their queries and this one did not. The shared helper inlibs/data-access/dot-localstorage/was never at fault and is unchanged.The param is now applied only when the URL actually carries
q.params.has('q')rather than a truthiness check, so a shared?q=link still clears the editor instead of silently resurrecting the previous query. Deep links keep winning over the restored value and still auto-run; a restored query is left in the editor unexecuted, matching the sibling dev tools.2. Velocity Playground example ran with warnings
The pull files example referenced
$f.fileSize, which is not a contentlet property — it resolved to null on every pulled file, so running the example greeted the user with fiveNULL_METHOD_RESULTwarnings and printed the literal$f.fileSizein the output (the screenshot on the issue).Size is a metadata-backed getter on
FileAsset(getFileSize()→getMetadata().getSize()), reachable through thefileAssetbinary field (FileAssetAPI.BINARY_FIELD, andFileAssetMap extends FileAsset). The example now reads$f.fileAsset.fileSize.fileNameandmimeTypedo resolve on the contentlet, which is what made the mistake easy to miss.I audited the other three Velocity examples and the Query Tool / ES Search example catalogs: all references resolve. The warnings banner is Velocity-only — it is fed by the VTL endpoint's
CollectingInvalidReferenceHandler, so the other two portlets have no equivalent surface to clear.Also checked (no code needed)
Three acceptance criteria on the issue are still unticked but were in fact delivered by #36781 — I verified rather than reimplemented:
libs/data-access/src/lib/dot-localstorage/(not duplicated per portlet)store.clearPersistedQuery()in their templatesTest plan
portlets-dot-query-tool-portlet— 58 testsportlets-dot-velocity-playground-portlet— 124 testsnx affected -t test --base=origin/main— 2,726 tests across 4 projectsnx affected -t lint+nx format:checkclean?q=...Query Tool link — the deep link wins over the stored query and auto-runsThe Velocity fix was verified by reading the Java (
FileAssetAPI,FileAsset.getFileSize(),ContentMap's binary-field branch), not by running it against an instance — worth an extra look during QA.Testing notes
The new regression coverage sits in a dedicated
describethat uses the real store. Every other describe in that spec mocksDotQueryToolStore, so the store-onInit-before-ngOnInitordering was structurally invisible to them — which is how this shipped green. It covers restore-on-reopen, deep-link precedence, and that the stored entry is never erased. Confirmed failing first (expected '' to be '+contentType:Blog'), then passing.🤖 Generated with Claude Code
This PR fixes: #36692