Nested Entities in Form

Hi,

I have a record which looks roughly like this:

` public static class AlbumRecord {
public static class FamilyRecord {
@NotNull
public UUID id;

        public String name;

        public FamilyRecord() { }
        public FamilyRecord(Family family) {
            this.id = family.getId();
            this.name = family.getName();
        }
    }

    public UUID id;

    @NotNull
    public FamilyRecord family;

    @NotNull
    @Size(min = 1, max = 32)
    public String name;

    public AlbumRecord() { }
    public AlbumRecord(Album album) {
        this.id = album.getId();
        this.name = album.getName();
    }
}`

Then a form with two fields:

  • an input type=text called “name” bound with {…form.field(form.model.name)}
  • a select called “family.id” bound with {…form.field(form.model.family.id)}

However, when the form is submitted, the serialized JSON results only in:
{ name: ‘something here’, family: { id: null, name: null } }

Notably the nested family object has only null values, even though the field “family.id” does have a value selected in the form.

Two questions:

  1. Can someone please help me figure out how to correctly bind/serialize/submit nested properties like this? (is there a tutorial or example I have missed?)
  2. What is the appropriate way to review/debug bound parameters in the request lifecycle on the server-side? For example, if I want to set a breakpoint to review property bindings/request parameterMap before they hit my @Endpoint, how is this best audited?

Thank you!

Hi @logical-gazelle, sorry for the late response, Christmas times are a bit challenging :sweat_smile:

Anyway, could you elaborate more about which version of Hilla are you using?

Regarding your second question, I can point out the name of the EnpointInvoker class (it is in the endpoint dependency). You can put a breakpoint in the invoke method, and then you can follow the process of deserializing and validating the input params from there on the server-side. Is that what you were looking for?

Hi @zen-quetzal, thanks so much for your response. Sorry for the late reply… I’ve been switching stacks between Spring/Hilla and Rails/Inertia trying to see what I like best for a new project…

As it turns out, I was complicating my issue because I was using BlueprintJS input components which require ‘ref’ remapped to ‘inputRef’. I’ve gotten a little more comfortable with React in the past few weeks, though not much…but I understand why I was seeing badly serialized form data.

@zen-quetzal – I have a related issue, and if there is a code example somewhere on Github it might just answer my question – but it seems Hilla is not very widely used as of yet…

Take this very simple form (TextInput and SelectInput are just custom components wrapping a bunch of stuff, and ultimately using the field(…) form binding):

            <TextInput
                model={form.model.name}
                label="Album Name"
                sublabel="Enter a name for this album."
            />
            <SelectInput
                model={form.model.family}
                label="Family"
                sublabel="Which family owns this album?"
            >
                {families.map(family => (
                    <option key={family.id} value={family.id}>{family.name}</option>
                ))}
            </SelectInput>

There exists two simple Hilla TypeScript models: AlbumRecordModel (id: StringModel, family: FamilyRecordModel, name: StringModel)…and FamilyRecordModel (id: StringModel, name: StringModel).

When the form is submitted to my AlbumService, the request is serialized as:
{
“id”: null,
“family”: “3db98a69-5e5c-4e0a-b725-a05d63deb2b4”,
“name”: “asdf”,
}

I think I would expect (although not sure how) to send something more like:
{
“id”: null,
“family”: {“id”: “3db98a69-5e5c-4e0a-b725-a05d63deb2b4”},
“name”: “asdf”,
“tags”: null
}

Are there any examples out there that illustrate how to properly bind into nested objects on both the client and server side?

Thank you again for your help!

Well, generally speaking, for nested objects, Hilla provides the useFormPart hook that you can use it for binding the nested objects’ properties to the form fields. The general documentation about useFormPart is available here:
https://hilla.dev/docs/react/guides/forms/reference#the-field-directive

The following might not exactly about what you asked, but demonstrates other usages of the useFormPart:
https://hilla.dev/docs/react/guides/forms/binder-validation#single-field-ts-validators

Hi @logical-gazelle, I baked a quick dirty example for using useFormPart while dealing with a nested object structure: https://github.com/taefi/hilla-nested-objects-react-forms
Note that it is not a best practice for designing entities nor UI components, it just showcase the API usage. For example, you can take it to the next level by creating a separate component that handles the ContactInfo or Address sub-forms (In my example, they are all part of the same form for the sake of simplicity).