My goal is to select a Student and with onChange to dynamically setFieldValues for the FieldArray of their nested schedule array of objects.
When I select Student: 1, I should get an array of fields for each of their 3 schedule items, Student 2: will have example 4 items. Example relates to something such as this older example with Fruit on CodeSandbox. A second CodeSandbox also related for this.
My problem is that when I try to map a student's schedule it shows schedule.map is a TypeError. Thus not populating my FieldArray with the fields to be edited.
TypeError: values.schedule.map is not a function
My JSON data:
{
"count": 2,
"results": [
{
"id": "1",
"name": "Tom",
"schedule": [
{
"class": "GYM",
"time": "9:00,
},
{
"class": "History",
"time": "10:00",
},
{
"class": "Lunch",
"time": "11:00",
},
},
{
"id": "2",
"name": "Nancy",
"schedule": [
{
"class": "Math",
"time": "9:00,
},
{
"class": "Science",
"time": "10:00",
},
{
"class": "English",
"time": "11:00",
},
{
"class": "History",
"time": "12:00",
},
}
]
}
My Formik Component:
const NewStudentSchedule = () => {
const [studentSchedule, setSchedule] = useState([]);
useEffect(() => {
const getSchedule = async () => {
try {
const { data } = await fetchContext.authAxios.get(
`/api/schedule/`
);
setSchedule(data.results);
// console.log(data);
} catch (err) {
console.log(err);
}
};
getSchedule();
}, [fetchContext]);
const initialValues = {
id: '',
schedule: [
{
class: '',
time: '',
},
],
};
return (
<Formik
initialValues={initialValues}
onSubmit={async (values, { resetForm }) => {
alert(JSON.stringify(values, null, 2));
resetForm();
}}
>
{({
isSubmitting,
values,
setFieldValue,
handleChange,
errors,
touched,
}) => (
<Form>
<div className="row">
<div className="col-md-6 mr-auto">
<div className="form-group">
<label htmlFor="status">STUDENT</label>
<Field
className="form-control"
as="select"
name="id"
onChange={(event) => {
handleChange(event);
const selectedTask = schedule.find(
(selectStudent) => selectStudent.id === event.target.value
);
setFieldValue(
`schedule.step`,
selectedTask.schedule.step
);
}}
>
<option value="" defaultValue disabled>
...
</option>
{schedule &&
schedule.map((i) => (
<option key={i.id} value={i.id}>
{i.name}
</option>
))}
</Field>
</div>
</div>
</div>
<div className="col-md-12">
<h3 className="pt-3">CREATE SCHEDULE</h3>
<FieldArray name="schedule">
{({ insert, remove, push }) => (
<>
{values.schedule.length > 0 &&
values.schedule.map((task, index) => (
<div className="row" key={index}>
<div className="col-11">
<div className="row">
<div className="col">
<div className="form-group">
<label
htmlFor={`schedule.${index}.class`}
>
CLASS
</label>
<Field
className="form-control"
name={`schedule.${index}.class`}
type="text"
/>
</div>
</div>
<div className="col">
<div className="form-group">
<label
htmlFor={`schedule.${index}.time`}
>
TIME
</label>
<Field
className="form-control"
name={`schedule.${index}.time`}
type="text"
/>
</div>
</div>
</div>
</div>
<div className="col-1">
<button
type="button"
className="btn delete"
onClick={() => remove(index)}
>
Delete
</button>
</div>
</div>
))}
<button
type="button"
className="btn add"
onClick={() => push({ class: '', time: '' })}
>
Add
</button>
</>
)}
</FieldArray>
<button
className="btn float-right mb-5"
type="submit"
disabled={isSubmitting}
>
SUBMIT
</button>
</div>
</Form>
)}
</Formik>
)
}

