0

I want to make a Quiz App.

Questions are checked after user presses Submit button.

So questions are checked all at once in the end.

I need to save user choices (answers) for each question and then later check them on submit.

I was thinking about this:

let [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
let [userAnswers, setUserAnswers] = useState([] as any);

  function answerClick(value: any, key: any) {
    // console.log('answer clicked');
    userAnswers[currentQuestionIndex][key] = value; 
    // TypeError: undefined is not an object (evaluating 'userAnswers[currentQuestionIndex][key] = value')
  }

My checkbox for each possible answer in the question:

<BouncyCheckbox
   key={index}
   onPress={(value) => {
      answerClick(value, index);
   }}
   text={answer.title}
/>

But I get

TypeError: undefined is not an object (evaluating 'userAnswers[current][key] = value')

on Answer click

What is setUserAnswers() equivalent of userAnswers[currentQuestionIndex][key] = value?

Why am I getting undefined error?

How to do this, please help my head hurts.

reactnDev
  • 3
  • 2
  • have you tried using a debugger inside your `answerClick` function to see what is coming through? – TR3 Sep 20 '21 at 13:53
  • Welcome to Stack Overflow! Just wanted to point out that *"How to do this, please help my head hurts."* Isn't recommended in SO questions. – I_love_vegetables Sep 27 '21 at 07:59

2 Answers2

0

First off, the userAnswers should have the key and values of everything you're trying to change. The reason you're getting undefined is because you're trying to target an object in the userAnswers array which can't be found. Also, you are modifying the userAnswers state directly and that's really wrong. That's what the setUserAnswers is for. You can do this instead.

function answerClick(value: any, key: any) {
    // console.log('answer clicked');
    setUserAnswers([
        ...usersAnswers,
        {[key]: [value]}
    ]);
  }

0

You are attempting to access a non existing index in the array.

userAnsqers = [];
currentQuestionIndex = 0;
// userAnswers[currentQuestionIndex] === undefined

What are you attempting to do is adding an {} to the array lazily (only when needed). This will work:

function answerClick(value: any, key: any) {
  setUserAnswers(latest => {
    const out = [...latest];
    while (out.length <= currentQuestionIndex) out.push({});
    out[currentQuestionIndex][key] = value;
    return out;
  })
}

There is nothing equivalent to setUserAnswers() for userAnswers[currentQuestionIndex][key] = value (see). You may find som custom hooks to manage arrays or build your own.

Newbie
  • 4,462
  • 11
  • 23
  • Thank you for your help. How can I remember user choices for each question. So when I go to 3rd question, old choices should be there. I cannot put `isChecked={userAnswers[current][index]}` on my checkbox element because on render I get the same undefined error. – reactnDev Sep 20 '21 at 14:24
  • `isChecked={userAnswers.length > current && userAnswers[current][index]` – Newbie Sep 20 '21 at 14:32
  • But you should consider providing more context so we can give you a more solid answer – Newbie Sep 20 '21 at 14:33
  • Thank you again. I made a sandbox. Please take a look at it. It's not working properly. UserAnswers apply to all questions, they are not per question (unique). https://codesandbox.io/s/sleepy-hellman-4nym1?file=/src/App.tsx:3037-3046 – reactnDev Sep 20 '21 at 14:48
  • https://codesandbox.io/s/jovial-ellis-num8e (read `disableBuiltInState` documentation of `BouncyCheckbox`, either you manage `isChecked` or let it to the checkbox. In which case you will be facing with React recycling components) – Newbie Sep 20 '21 at 15:08