Apply JSON to TextFields or Selects based on a value in the JSON

All we need is an easy explanation of the problem, so here it is.

I have a bunch of JSON groups pulled from an API. Each group contains 1 or more questions objects. I need to append each question to a textField with its corresponding response in either a MUI TextField or Select, which needs to be decided based on the QuestionType value.

Below is how I am trying to get data to display to a TextField. The TextFields are being populated with [object Object] as they are now.

const [questions, setQuestions] = useState("");

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

...

{questions["question_groups"]?.map((row) => (
   <TextField
      fullWidth
      multiline
      className="text-field"
      value={row?.questions || ""}
      variant="outlined"
      margin="normal"
      label={row["GroupName"]}
   />
))}

Here is an example of my JSON. In reality, there could be 20 groups within question_groups

{
   "question_groups": [
      {
         "GroupName": "DDD",
         "questions": [
            {
               "Question": "1. Do you need a drink?",
               "QuestionType": "Select",
               "Response": null,
               "Choices": [
                  "Yes",
                  "No"
               ]
            }
         ]
      },
      {
         "GroupName": "FED",
         "questions": [
            {
               "Question": "2. What do you want to drink?",
               "QuestionType": "Text",
               "Response": null,
               "Choices": [
               ]
            },
            {
              "Question": "3. Do you want something to eat?",
               "QuestionType": "Text",
               "Response": "I would like steak",
               "Choices": [
               ] 
            }
         ]
      }
   ],
}

Any help or advice would be greatly appreciated.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Create two components for each QuestionType.

const SelectQuestion = ({ question }) => {
 return (
        <Box>
          <TextField value={question?.Question || ""} />
          <Select label="Question" >
            <MenuItem value={question?.Choices || ""}>{question?.Choices || ""}</MenuItem>
          </Select>
          <Divider />
        </Box>
      );
};

const TextQuestion = ({ question }) => {
      return (
        <Box>
          <TextField value={question?.Question || ""}/>
          <TextField />
          <Divider />
        </Box>
      );
};

Map the array of question_groups, then map the array of questions in each group and return one of the component types depending on the value of QuestionType

const questionComps = questions["question_groups"]?.map((group, i) => {
        return group["questions"]?.map((question, i) => {
            return question["QuestionType"] === "Text" ? (
                <Box>
                    <TextQuestion key={`${i}${question.Question}`} question={question} />
                    <Divider />
                </Box>
            ) : (
                <Box>
                    <SelectQuestion key={`${i}${question.Question}`} question={question} />
                    <Divider />
                </Box>
            );
        });
    });

Now render the question components

return (
        <div>{questionComps}</div>
    )

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply