Home > front end >  Cant output answer buttons and sort them in my project
Cant output answer buttons and sort them in my project

Time:02-08

im trying to make a quizz project fetching api of quiz with answers and questions im so in the api there is array of wrong answers(3) and one correct answer i try to output them as buttons and i outtput the 3 wrong answers so i thought i would push the correct answer into the wrong answers array and then randomly sort them and output as answers but i get the errot that array of answers isnt iterable can anyone help me to solve this problem and tell me if im going in the right direction or not ?


import './App.css';
import axios from 'axios'
import {useState,useEffect} from 'react'

function App() {
  const [quiz,setQuiz] = useState([])
  const [answer,setAnswer] = useState([])
  useEffect(()=>{
    axios.get('https://opentdb.com/api.php?amount=10')
    .then(res=>{
     
      setQuiz(res.data.results[0])
     
       setAnswer([...quiz.incorrect_answers, quiz.correct_answer])
    })
    .catch(err=>{
      console.log(err);
    })
 
  },[])



  return (
    <div className="App">
   <h1>{quiz.question}</h1>
   {answer && answer?.map(answers =>
   <button key={answers}>{answers}</button>)
  
   }
    </div>

  );
}

export default App;

CodePudding user response:

useEffect(()=>{
    axios.get('https://opentdb.com/api.php?amount=10')
    .then(res=>{
       setQuiz(res.data.results[0])
       let tempVar = res.data.results[0] ;
       setAnswer([...tempVar.incorrect_answers, tempVar.correct_answer])
    })
    .catch(err=>{
      console.log(err);
    })
 
  },[])

Your useEffect should look like this. As changing a state is an asynchronous task . That is why you are getting error that quiz.incorrect_answers is not iterable. I hope this solves your issue .

CodePudding user response:

You can't set state and use it immediately, you need to await the set state changes. You can handle that properly by adding a useEffect to be executed every time quiz changes you code will look like that

  useEffect(() => {
    axios
      .get("https://opentdb.com/api.php?amount=10")
      .then((res) => {
        setQuiz(res.data.results[0]);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

  useEffect(() => {
    if (quiz.length > 0)
      setAnswer([...quiz.incorrect_answers, quiz.correct_answer]);
  }, [quiz]);

OR You can use .then function to handle that in the same useEffect

useEffect(() => {
    axios
      .get("https://opentdb.com/api.php?amount=10")
      .then((res) => {
        setQuiz(res.data.results[0]);
      }).then(()=>setAnswer([...quiz.incorrect_answers, quiz.correct_answer]))
        
      .catch((err) => {
        console.log(err);
      });
  }, []);

CodePudding user response:

Here's an approach you can use:

function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i   1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}
// This here is a function to shuffle the array for you

const [quiz,setQuiz] = useState(null)
// use a null value for the quiz, null checking will be done in the h1 render component
const [correct_answer,setAnswerCorrect] = useState([])
// from the result, the correct answer is a string
const [incorrect_answers,setAnswersIncorrect] = useState([])
// and the incorrect answers are in form of an array
// that's why the separation
let all_answers = [];
useEffect(()=>{
    axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
    
        setQuiz(res.data.results[0])
    
        setAnswerCorrect([res.data.results[0].correct_answer])
        setAnswersIncorrect(res.data.results[0].incorrect_answers);
        // first update all the values
    })
    .catch(err=>{
    console.log(err);
    })

},[])

Then from here check whether the question has loaded first, if not, show that the question is loading:

<h1>{quiz ? quiz.question : 'Question loading...'}</h1>
// check whether the question has loaded before outputting it
{
    all_answers = correct_answer && incorrect_answers ? shuffleArray(correct_answer.concat(incorrect_answers)) : ''
// join the two arrays, for the correct and incorrect answers then shuffle the values
}
{
    all_answers?.map(answers =>
    <button key={answers}>{answers}</button>)
}
  •  Tags:  
  • Related