I'm building a dashboard using refine.dev
and AntDesign
.
One of my entities has Many-to-Many relation that is returned in the API as an array of objects with id
properties.
{
"id": 1,
"relations": [
{
"id": 1
},
{
"id": 2
}
]
}
I need to build a form with a “multiple select” component. And I follow this tutorial. But unfortunately, it has examples only for “many-to-one” relations.
First I generate selectProps
. This part goes all right.
const { selectProps: relationsSelectProps } = useSelect<Relation>({
resource: 'relations',
optionLabel: 'name',
defaultValue: record?.relations.map((r) => r.id),
});
Then starts the problem. When I'm trying to create a form item
<Form.Item
name={['relations']}
>
<Select
mode="multiple"
{...relationsSelectProps}
/>
</Form.Item>
I can't make it work with multiple nested objects.
I tried different name paths: ['relations', 'id']
, and ['relations', '*', 'id']
Tried to play around with the normalize
property.
I don't really want to flatten these objects on the backend side, so the question is: what's the best practice to make this work on the react side of the project?
So you can do this thing by adding two properties to the Form.Item
component.
getValueFromEvent
to transform Select's values to formgetValueProps
to do it the other way around<Form.Item
name={['relations']}
getValueFromEvent={(values) => {
return values.map((id: number) => ({ id }));
}}
getValueProps={(ids) => {
return ids?.map(({ id }: { id: number }) => id);
}}
>
<Select
mode="multiple"
{...selectProps}
/>
</Form.Item>
Then the post (patch) request's gonna look the right way:
{
"relations": [
{ "id": 1 },
{ "id": 2 }
],
// other fields
}