'Uncaught TypeError: is not iterable when trying to edit text in a TextField

I am trying to allow MUI TextFields to be editable after populating them from an API.

I am getting the following error msg when I try to edit the TextFields: Uncaught TypeError: prev.fields is not iterable.

This is the function where the data is fetched from the API and input into the TextFields. The function displays data in either a TextField, DatePicker, or a Select box based on the value of FieldType in the JSON resaponse.

function IntakeDetails() {
    const params = useParams();
    const [details, setDetails] = useState('');

    const fetchDetails = async () => {
        setDetails(
            await fetch(`/fiscalyears/FY2023/intakes/${params.id}/details`).then(
                (response) => response.json()
            )
        );
    };

    useEffect(() => {
        fetchDetails();
    }, []);

    return (
        <Container maxWidth="xl">
            <Box>
                <h3> Intake Details </h3>
            </Box>
            <Box>
                {details["groups"]?.map((group, i) => {
                    return (
                        <Accordion>
                            <AccordionSummary expandIcon={<ExpandMoreIcon />}
                                <Typography>{group?.GroupName}</Typography>
                            </AccordionSummary>
                            <AccordionDetails>
                                <Box>
                                    {group["fields"]?.map((row, index) => {
                                        if (
                                            row?.FieldType === "Text" ||
                                            row?.FieldType === "Decimal" ||
                                            row?.FieldType === "Number"
                                        ) {
                                            return (
                                                <TextField
                                                    value={row?.Value || ""}
                                                    onChange={(e) => {
                                                        setDetails((prev) => {
                                                            const update = [...prev.fields];
                                                            update[index] = {
                                                                ...update[index],
                                                                Value: e.target.value,
                                                            };
                                                            return { ...prev, fields: update };
                                                        });
                                                    }}
                                                    label={row["FieldName"]}
                                                />
                                            );
                                        }
                                        if (row?.FieldType === "Date") {
                                            return (
                                                <TextField
                                                    type="date"
                                                    value={row?.Value || null}
                                                    onChange={(e) => {
                                                        setDetails((prev) => {
                                                            const update = [...prev.fields];
                                                            update[index] = {
                                                                ...update[index],
                                                                Value: e.target.value,
                                                            };
                                                            return { ...prev, fields: update };
                                                        });
                                                    }}
                                                    label={row["FieldName"]}
                                                    InputLabelProps={{ shrink: true, }}
                                                />
                                            );
                                        } else {
                                            return (
                                                <TextField
                                                    value={row?.Value || ""}
                                                    onChange={(e) => {
                                                        setDetails((prev) => {
                                                            const update = [...prev.fields];
                                                            update[index] = {
                                                                ...update[index],
                                                                Value: e.target.value,
                                                            };
                                                            return { ...prev, fields: update };
                                                        });
                                                    }}
                                                    select
                                                    label={row?.FieldName}
                                                >
                                                    {row?.Choices.map((choice) => (
                                                        <MenuItem key={choice} value={choice}>
                                                            {choice}
                                                        </MenuItem>
                                                    ))}
                                                </TextField>
                                            );
                                        }
                                    })}
                                </Box>
                            </AccordionDetails>
                        </Accordion>
                    );
                })}
            </Box>
        </Container>
    );
}

The JSON response from the API looks like this:

{
  "groups": [
    {
      "GroupName": "Details",
      "GroupOrder": 1,
      "fields": [
        "FieldId": 2,
        "FieldName": "Day",
        "FieldType": "Select",
        "Value": "Option1",
        "Choices": [
          "Option1",
          "Option2"
        ]
      ]
    },
    {
      "GroupName": "Attributes",
      "GroupOrder": 2,
      "fields": [
        {
          "FieldId": 2,
          "FieldName": "Night",
          "FieldType": "Text",
          "Value": "Night time",
          "Choices": [
            null
          ]
        },
        {
          "FieldId": 3,
          "FieldName": "Todays Date",
          "FieldType": "Date",
          "Value": "2020-08-12",
          "Choices": [
            null
          ]
        }
      ],
    }
  ]
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source