I'm currently trying to build a form with React and Material UI, where my final payload has to look like this:
{
title: title,
quadrants: {
0: { name: quadrantOne },
1: { name: quadrantTwo },
2: { name: quadrantThree },
3: { name: quadrantFour }
}
}
The corresponding part of my form (including initial values) is structured as follows:
const initialValues = {
title: '',
quadrants: {},
};
const [values, setValues] = useState(initialValues);
const handleInputChange = (e: any) => {
const { name, value } = e.target;
setValues({
...values,
[name]: value
});
};
return (
<Form>
<Grid item xs={12} sm={12}>
<Input
name="title"
label="Title"
value={initialValues.title}
onChange={handleInputChange}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Input
name="quadrant-one"
label="Quadrant 1"
value={initialValues.quadrants}
onChange={handleInputChange}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Input
name="quadrant-two"
label="Quadrant 2"
value={initialValues.quadrants}
onChange={handleInputChange}
/>
</Grid>
</Form>
)
In this way, my input fields look like this, so that I cannot enter anything in the fields::
But if I enter something in the fields (the entry is not visible), then I get the following payload:
{
title: "Test"
quadrants: {}
quadrant-one: "[object Object]"
quadrant-two: "[object Object]"
}
The entries are not nested in the "quadrants" object, but entries appear in the payload with the name of the respective form element (Like quadrant-one, quadrant-two..).
What am I doing wrong here and how can I fix this?
You are getting [Object Object]
because initialValues.quadrants is an object, I assume you are trying to set initialValues.quadrants[0].name, but as initial value initialValues.quadrants[0] is undefined
You need to apply some changes. I recommend you define a custom attribute (data-index) for the quadrants input, this way on input change you can update the correct object. Also for the quadrants inputs you can define a function to get the value because at first render it value is undefined:
const initialValues = {
title: "",
quadrants: {}
};
const [values, setValues] = useState(initialValues);
const handleInputChange = e => {
const { name, value } = e.target;
const dataIndex = Number(e.target.getAttribute("data-index"));
setValues(prev => {
if (name === "title") {
return {
...prev,
[name]: value
};
} else {
return {
...prev,
quadrants: {
...prev.quadrants,
[dataIndex]: { name: value }
}
};
}
});
};
const getValue = prop => {
const value = values.quadrants[prop] ? values.quadrants[prop].name : "";
return value;
};
return (
<Form>
<Grid item xs={12} sm={12}>
<Input
name="title"
label="Title"
value={values.title}
onChange={handleInputChange}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Input
name="quadrant-one"
label="Quadrant 1"
data-index="0"
value={getValue(0)}
onChange={handleInputChange}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Input
name="quadrant-two"
label="Quadrant 2"
data-index="1"
value={getValue(1)}
onChange={handleInputChange}
/>
</Grid>
</Form>
)