Reputation: 63
What I want is to display the amount of answers you got right on the trivia at the end of the 10 question quiz. I have everything working up to this point. I expect it to display the number of correct answers, but instead I get an error "cannot read property of undefined" pointing to this line
<p> {results.correct} </p>
Here's the whole component, I hope I labeled everything well enough to make it readable
function App() {
//useState variables
const [results, setResults] = useState({
correct: 0,
answer: "True",
});
const [arrayIndex, setArrayIndex] = useState(0);
const [classOn, setClassOn] = useState("trivia-cards-initial");
const [triviaArray, setTriviaArray] = useState([]);
const [disable, setDisable] = useState(true);
//useEffects
useEffect(() => {
axios
.get("https://opentdb.com/api.php?amount=10&difficulty=hard&type=boolean")
.then((res) => {
setTriviaArray(res.data.results);
});
}, []);
//onclicks and helper functions
const nextQuestionOnClick = () => {
setClassOn(`trivia-cards-initial-${arrayIndex}`);
// setTriviaArray(triviaArray);
setResults(() => {
if (triviaArray[arrayIndex].correct_answer === results.answer) {
setResults({ ...results, correct: results.correct + 1 });
} else {
setResults({ ...results });
}
});
setArrayIndex(() => {
if (arrayIndex > 8) {
return 9;
} else {
return arrayIndex + 1;
}
});
console.log(triviaArray);
console.log({ ...results });
};
const beginOnClick = () => {
setClassOn(`trivia-cards-initial-${arrayIndex}`);
// setTriviaArray(triviaArray);
setArrayIndex(() => {
if (arrayIndex > 8) {
return 9;
} else if (arrayIndex === 0) {
return arrayIndex;
} else {
return arrayIndex + 1;
}
});
};
const answerButtonTrue = () => {
setResults({
...results,
answer: "True",
});
setDisable(false);
};
const answerButtonFalse = () => {
setResults({
...results,
answer: "False",
});
setDisable(false);
};
function calculator() {
return results.correct;
}
//JSX
if (classOn === "trivia-cards-initial") {
return (
<div className={classOn}>
<h1 className="title">Welcome To The Trivia Challange!</h1>
<h3 className="text-content-middle">
You will be presented with 10 True or False questions.
</h3>
<h3 className="text-content-bottom">Can you score 100%?</h3>
<div className="begin-btn-bg">
<button className="buttons" onClick={beginOnClick}>
BEGIN
</button>
</div>
</div>
);
} else if (classOn === "trivia-cards-initial-9") {
return (
<div>
<p> {results.correct} </p>
</div>
);
} else {
return (
<div className="bg-cards">
<div className="trivia-cards">
<div className={classOn}>
<h2 className="category">{triviaArray[arrayIndex].category}</h2>
<h3 className="trivia-questions">{`${triviaArray[arrayIndex].question}`}</h3>
<button className="true-btn" onClick={answerButtonTrue}>
True
</button>
<button className="true-btn" onClick={answerButtonFalse}>
False
</button>
<p>Correct Answer:{triviaArray[arrayIndex].correct_answer}</p>
<button
className="buttons"
onClick={nextQuestionOnClick}
disabled={disable}
>
Next Question
</button>
</div>
</div>
</div>
);
}
}
Upvotes: 1
Views: 34
Reputation: 167220
Most likely it's due to uninitialised variables and you have to handle it properly. Please use something like this:
{results && typeof results.correct !== "undefined" && (
<p> {results.correct} </p>
)}
Here you're checking if results
and results.correct
are truthy, before trying to display it. This should fix it. Let me know.
Or in simple way, you can do:
{results && results.correct > -1 && (
<p> {results.correct} </p>
)}
The above one is because, what if results.correct
is 0
!
Upvotes: 1