Skip to content

fix: materialize nested placeholder hasOne for <HasOne> JSX#33

Open
vparys wants to merge 2 commits into
mainfrom
fix/placeholder-hasone-nested-materialization
Open

fix: materialize nested placeholder hasOne for <HasOne> JSX#33
vparys wants to merge 2 commits into
mainfrom
fix/placeholder-hasone-nested-materialization

Conversation

@vparys
Copy link
Copy Markdown
Member

@vparys vparys commented May 14, 2026

Summary

<HasOne field={…}> over a nullable has-one relation whose parent is itself a placeholder (e.g. an outer disconnected has-one) called its children callback with undefined, crashing on the first field access. PlaceholderHandle.createPlaceholderFieldHandle only branched on has-many — has-one fell through to the scalar fallback, which has no $entity.

What's in here

  • Adds a has-one branch to PlaceholderHandle.createPlaceholderFieldHandle that returns a HasOne-shaped handle backed by a freshly created nested PlaceholderHandle for the inner target type. $entity resolves to the nested placeholder, and field-access proxying (placeholder.profile.bio…) forwards into it, mirroring the single-level placeholder ergonomics.
  • Mutations ($create, $connect) on a nested placeholder throw with a clear message — the outer placeholder has no backing row to attach a child to. $disconnect/$delete/$remove/$reset no-op (the relation is already disconnected). Writes to scalar fields under a nested placeholder are an explicit non-goal here; the issue only asks for the read path to stop crashing.
  • Regression test: tests/react/jsx/HasOneNullRelation.test.tsx (Article → Author=null → Profile chain). It fails on main with TypeError: undefined is not an object and passes with the fix.

Test plan

  • bun test tests/react/jsx/HasOneNullRelation.test.tsx — passes
  • bun test tests/react/relations/hasOne/ tests/react/jsx/ — 87 pass, 0 fail
  • bun test whole suite — same 9 pre-existing failures as on main (Storybook stories + one unrelated form has-many dirty-state test), no new regressions
  • bun run typecheck — clean

Fixes #32

vparys added 2 commits May 14, 2026 13:44
… defined ref

PlaceholderHandle only handled has-many in its field-access proxy, so a
has-one relation accessed on a placeholder entity fell through to the
scalar fallback and exposed no $entity. <HasOne field={placeholder.hasOneField}>
then called children(undefined), crashing on the first field access.

Adds an explicit has-one branch that returns a nested-placeholder
has-one handle with $entity wired to an inner PlaceholderHandle, plus
field-access proxying so chains like placeholder.profile.bio resolve to
the inner placeholder's field handle instead of undefined. Mutations
on the nested placeholder ($create/$connect) throw with a clear message,
since the outer placeholder has no backing row to attach to.

Fixes #32
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.

HasOne JSX over nested nullable has-one passes undefined to children when both levels are placeholders

1 participant