Skip to content

fix(bindx): resolve auto-generated has-many alias on accessor reads (#53)#54

Merged
matej21 merged 1 commit into
mainfrom
fix/nested-hasmany-orderby-empty-accessor
Jun 25, 2026
Merged

fix(bindx): resolve auto-generated has-many alias on accessor reads (#53)#54
matej21 merged 1 commit into
mainfrom
fix/nested-hasmany-orderby-empty-accessor

Conversation

@matej21

@matej21 matej21 commented Jun 25, 2026

Copy link
Copy Markdown
Member

Closes #53.

Problem

A has-many relation selected with params (orderBy/filter/limit/offset) reads back as an empty list on the resulting accessor — list.items[i].<relation>.items is always []. Scalar siblings load fine; dropping the params makes the relation populate. The data is fetched correctly; it's lost between store and accessor.

Root cause

A has-many with params gets an auto-generated alias (generateHasManyAliastags_<hash>), so the fetched rows land in the entity snapshot under data['tags_<hash>']. The read path had two gaps:

  1. useEntity / useEntityList never threaded the selection into the root EntityHandle, so this.selection was undefined and no alias could be resolved.
  2. EntityHandle.fields passed undefined as the alias to hasMany(), so HasManyListHandle looked under data['tags'] (empty) instead of data['tags_<hash>'].

The consumer reads the relation by its real field name (tags) — it can't know the hash alias — so the read side must map field name → stored alias.

Fix

  • EntityHandle — new resolveSelectionField(name): direct lookup first, then for array relations falls back to matching on fieldName, recovering the auto-generated alias. The resolved alias + nested selection are threaded into hasMany(). The fallback is restricted to has-many so explicit scalar/has-one aliases still report unfetched when read by their original name.
  • useEntity / useEntityList — pass selectionMeta to the root EntityHandle (+ dep arrays).

This also makes the hooks selection-aware (UnfetchedFieldError), consistent with the already-validating <Entity> JSX path — it completes the existing selection design rather than changing it.

Tests

  • tests/react/hooks/useEntityList/nestedHasManyOrderBy.test.tsx — the reported repro (list path).
  • tests/react/hooks/useEntity/nestedHasManyOrderBy.test.tsx — companion single-entity path, also asserting orderBy is honored on read.

Verification

  • Full suite: only pre-existing failures remain — 9 tests/browser/* (need the live playground) and FormHasManyRelationScope › tracks dirty state (fails identically on clean main, verified in a worktree). Zero new failures.
  • Typecheck clean for the changed packages (the lone packages/example/App.tsx error is a pre-existing duplicate @contember/graphql-client install).

🤖 Generated with Claude Code

)

A has-many relation selected with params (orderBy/filter/limit/offset)
is stored under an auto-generated alias (e.g. `tags_<hash>`), but the
read path looked it up under the plain field name and came back empty.

Two gaps:
- `useEntity`/`useEntityList` never threaded the selection into the root
  `EntityHandle`, so `this.selection` was undefined and no alias could
  be resolved.
- `EntityHandle.fields` passed `undefined` as the alias to `hasMany()`,
  reading `data['tags']` instead of `data['tags_<hash>']`.

Fix: thread `selectionMeta` into the root handle in both hooks, and add
`EntityHandle.resolveSelectionField()` which recovers the stored alias by
matching on `fieldName` for array relations (scalar/has-one explicit
aliases still report unfetched when read by their original name). The
resolved alias + nested selection are threaded into `hasMany()`.

This also makes the hooks selection-aware (UnfetchedFieldError), matching
the existing `<Entity>` JSX path.

Adds regression tests for both the list- and single-entity accessor
paths, asserting orderBy is honored on read.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAKx7JbV7Z7EVXofqRgwop
@matej21 matej21 force-pushed the fix/nested-hasmany-orderby-empty-accessor branch from f802310 to 1cad4db Compare June 25, 2026 09:37
@matej21 matej21 merged commit ad21250 into main Jun 25, 2026
3 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.

Nested has-many selected with orderBy reads empty from list-loaded accessor

1 participant