Skip to content

Fix z.set() field values now properly displaying in subject table and export - #1544

Merged
joshunrau merged 4 commits into
DouglasNeuroInformatics:mainfrom
david-roper:fix-set-issue
Sep 15, 2026
Merged

joshunrau merged 4 commits into
DouglasNeuroInformatics:mainfrom
david-roper:fix-set-issue

Conversation

@david-roper

Copy link
Copy Markdown
Collaborator

Show z.set() record fields correctly in the subject table and its exports

Problem

Instrument records with a z.set() field showed the value as [object Set] in the subject table
(Data Hub → subject → Table), and every download from that page wrote it as {}.

The stored data was fine. The API saves a Set in libjs's serialized form, and useInstrumentRecords
parses the response with libjs's reviver, so the web client gets a real Set back. The bug was in
how the page turned that value into text:

  • Table cell: called String(value), which gives "[object Set]".
  • Downloads: used JSON.stringify, which writes a Set as {}.

The reviver is deliberately unchanged. The API and react-core need it to rebuild a real Set,
because z.set() validation rejects anything else.

Changes

apps/web

File Change
src/utils/record-value.ts (new) formatRecordValue(value): a Set becomes its values joined with ", "; anything else still goes through String(value).
src/routes/_app/datahub/$subjectId/table/index.tsx Table cells use formatRecordValue instead of String.
src/hooks/useInstrumentVisualization.ts When dl builds the export rows, it converts Set values with formatRecordValue, so every download option writes them as the table shows them.

Example: a Set of MONEY and FRIENDS now shows as MONEY, FRIENDS in the table and in every
download option (CSV, TSV, Excel, their "Long" versions, and JSON). CSV and TSV quote it because it
contains a comma. In JSON it is a string, not an array.

Tests

Unit (apps/web)

  • src/utils/__tests__/record-value.test.ts (new): covers a Set, a Set revived from the API's
    stored form, an empty Set, and other values.
  • src/hooks/__tests__/useInstrumentVisualization.test.ts: new set fields tests for the wide,
    long and JSON exports. The mock records are now built by a small factory and reset in
    beforeEach.

End-to-end (testing)

  • src/pages/_app/instruments/render/$id.page.ts:
    • New completeHappinessQuestionnaireDissatisfied(causes): answers "No", fills in the required
      reason, and ticks the given causes in causesOfDissatisfaction, the questionnaire's z.set()
      field.
    • The slider steps moved into a private setHappinessSliders shared with
      completeHappinessQuestionnaire, which behaves as before.
  • src/specs/instrument-completion.spec.ts: new z.set() fields group whose setup completes the
    questionnaire through the UI. That takes the Set through the form, the API and the database, and
    back into the web client.
    • One test checks the table cell reads MONEY, FRIENDS.
    • One test downloads the CSV and checks it contains "MONEY, FRIENDS".

The new unit and end-to-end tests fail without the fix. The table e2e test received
[object Set], and the export tests received {}.

Verification

  • pnpm lint: passes.
  • pnpm test: 143 files, 1167 tests pass.
  • pnpm test:e2e: 175 tests pass.

Known gaps (not in this branch)

  • Record summary view: InstrumentSummaryGroup in packages/react-core still shows a Set as
    {}.
  • Record updates: InstrumentRecordsService.updateById in apps/api saves the parsed data
    without the serializer, so editing a record that has a Set field probably stores it wrongly.
  • Group-wide export: the API's export was not checked for Set fields.
  • Flaky test: the graph-tab test in testing/src/specs/subject-detail.spec.ts timed out once
    under a full-suite run. It passed in Firefox and on 3 Chromium retries, and it is unrelated to
    this change.

Closes issue #1543

@joshunrau
joshunrau merged commit 195ca06 into DouglasNeuroInformatics:main Sep 15, 2026
2 checks passed
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.

2 participants