Home > Net >  Error when saving hook arrays, Uncaught TypeError: choices is not iterable
Error when saving hook arrays, Uncaught TypeError: choices is not iterable

Time:12-07

I am trying to create a simple MCQ exam form with choices and answers, whenever the user selects a choice, it is supposed to be added in to the array of choices.

Initially I have an array named exercises, which contains exercise objects, each object contains a question and 4 different choices and an answer => for example:

     exercises = {
       "question": "What is 2 2?",
       "firstChoice": "1",
       "secondChoice": "2",
       "thirdChoice": "3",
       "fourthChoice": "4",
       "answer":"4"
    }

Initially choices array, and value

    const [value,setValue] = useState('');
    const [choices,setChoices] = useState([]);

And this is the RadioGroup:

 {exercises && exercises.map((exercise,index)=>(
        <div>
        <FormLabel id="demo-error-radios">Question {index 1}: {exercise.question}</FormLabel>
        <RadioGroup
          aria-labelledby="demo-error-radios"
          name="quiz"
          value={value}
          onChange={(e) => {handleChoice(e)}}>
          <FormControlLabel value={exercise.firstChoice} control={<Radio />} label= {exercise.firstChoice} />
          <FormControlLabel value={exercise.secondChoice} control={<Radio />} label={exercise.secondChoice} />
          <FormControlLabel value={exercise.thirdChoice} control={<Radio />} label={exercise.thirdChoice} />
          <FormControlLabel value={exercise.fourthChoice} control={<Radio />} label={exercise.fourthChoice}/>
        </RadioGroup>
        </div>
          ))}

This is the handleChoice function, whenever an input of type radio is clicked, it pushes that value in to the array of choices.

const handleChoice = (e) =>{
    var updatedAnswers = [...choices];
    updatedAnswers = [...choices].push(e.target.value);
    console.log(updatedAnswers);
    setChoices(updatedAnswers);
}

When I try to run it, I get always the error "Uncaught TypeError: choices is not iterable", It is supposed to be updating the array of choices by adding the new selected choice to the old ones, Why does not it work?

CodePudding user response:

[...choices].push returns a number, which is the length of the new array. After that you setChoices(updatedAnsers), which turns choices into a number, so the next time choices is spread, it throws error because number is not iterable. Instead try this:

const handleChoice = (e) =>{
    var updatedAnswers = [...choices, e.target.value];
    console.log(updatedAnswers);
    setChoices(updatedAnswers);
}

CodePudding user response:

In your handleChoice method, you are setting choices to the return value of the push method.

updatedAnswer = [...choices].push(e.target.value)

This sets updatedAnswer to the array length (push returns the new array length). What you want is to just append to choices so that can be done as follows:

setChoices([...choices, e.target.value])

In fact the entire function could be simplified:

const handleChoice = ({ target: { value } }) => setChoices([...choices, value])

CodePudding user response:

The return value of push is the array's new length. So when you write:

 updated = [...choices].push(e.value.target);

updated is initially assigned 1, and that is what is save to state, and 1 (on the next choice) is not iterable, hence the error.

Change the code to:

const updated = [...choices, e.target.value];
setChoices(updated);

CodePudding user response:

You could try something like this in your handleChoice function:

  const handleChoice = (e) => {
    var updatedAnswers = choices;
    updatedAnswers.push(e.target.value);
    console.log(updatedAnswers);
    setChoices(updatedAnswers);
  };
  • Related