I am unable to display the answer buttons and organize them accordingly within my project

I'm currently working on a quiz project where I fetch an API containing quiz questions and answers. The API provides an array of wrong answers (3) along with one correct answer. My goal is to display these options as buttons, so I decided to push the correct answer into the wrong answers array, randomize them, and present them as choices. However, I encountered an error stating that the array of answers is not iterable. Can anyone assist me in resolving this issue and confirm if my approach is correct?


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;

Answer №1

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);
    })
 
  },[])

Ensure your useEffect function is correctly implemented as provided above. When changing state asynchronously, it may lead to errors like 'quiz.incorrect_answers is not iterable'. Following this structure should resolve the issue you are experiencing.

Answer №2

When setting state, you can't use it immediately; you must await the changes to state first. To handle this properly, add a useEffect hook that runs every time the quiz changes. Your code would look something like this:

  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]);

Alternatively, you can also use the .then function within the same useEffect to handle the state change:

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);
      });
  }, []);

Answer №3

Here's a method you can implement:

function randomizeArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        let j = Math.floor(Math.random() * (i + 1));
        let temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}
// Use this function to shuffle the elements of an array

const [question, setQuestion] = useState(null)
// Initialize 'question' with a null value, handle null case in rendering component
const [correctAnswer, setCorrectAnswer] = useState([])
// Store correct answer as string
const [incorrectAnswers, setIncorrectAnswers] = useState([])
// Store incorrect answers as an array

let allAnswers = [];
useEffect(() => {
    axios.get('https://opentdb.com/api.php?amount=10')
        .then(res => {
    
        setQuestion(res.data.results[0])
    
        setCorrectAnswer([res.data.results[0].correct_answer])
        setIncorrectAnswers(res.data.results[0].incorrect_answers);
        // Update values after API call success
    })
    .catch(err => {
        console.log(err);
    })

}, [])

Next, check if the question has been loaded before displaying it:

<h1>{question ? question.question : 'Loading question...'}</h1>
// Display the question only after loading
{
    allAnswers = correctAnswer && incorrectAnswers ? randomizeArray(correctAnswer.concat(incorrectAnswers)) : ''
// Merge correct and incorrect answers arrays, then shuffle them
}
{
    allAnswers?.map(answer =>
    <button key={answer}>{answer}</button>)
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Utilizing CSS exclusively in conjunction with a PHP API for seamless integration

My CSS is working only when inline, and I'm struggling to track down the reason for this issue. As a beginner in web design, I am unsure of what steps to take to troubleshoot the problem. Since I cannot open the console to check for errors, what facto ...

Elegant Bootstrap 4 Carousel featuring a glimpse of the upcoming slide alongside the primary carousel item

I am in search of a straightforward Bootstrap 4 carousel that showcases a glimpse of the next slide on the right. Despite exploring similar questions, I have not found a suitable solution. The links to those questions are: 1)Bootstrap carousel reveal part ...

Is it feasible to achieve a full 100% screen width within a confined div using relative positioning?

Can a div expand to 100vw within a parent div that is relative and has a limited width, without losing its height in the document like it would if positioned absolute? Is it achievable with pure CSS or do I need some jQuery or JS? body { background: ...

Making a Request on Behalf of a Component in Vue.js Using Interceptors

Within my Vue application, I've implemented a response interceptor: axios.interceptors.response.use(function (config) { return config; }, error => { if (error.response.status !== 401) { return new Promise((resolve, ...

Tutorial on how to update a specific value in an array of objects using setState on click event

I need to toggle the active class on click, setting it to a local state and changing all other objects in the state to inactive. const [jobType, setJobType] = useState([ { "class": "active", "type& ...

Determine the placement of a <div> based on information stored in localStorage

I'm diving into the world of localStorage and trying to figure out how it works. To get a better understanding, I decided to create an HTML page that allows users to drag and drop tiles around the screen. Here's a snippet of the code I came up ...

Error occurred during NextJs deployment due to an issue with the getStaticPath function: An unexpected token "<" was found in the JSON at position 0 while trying to parse it

I've created this function to retrieve a path that will be used during local development mode. export async function getStaticPaths(){ const datas = await fetch(`https://mydomain.vercel.app/api/annonces/annonces`) const annonces = await datas. ...

When the Button is clicked, the component utilizing the Router fails to appear

My current task involves creating a page where users can choose between two options: Button 1 leads to TestOption.js, while Button 2 redirects to TestOption2 (currently using TestOption for testing purposes). The default landing page is SelectionPage. The ...

Retrieving Array keys from PHP using jQuery

As a beginner in jQuery, I am eager to learn how to retrieve Array keys from a php file using jQuery. Currently, I have jQuery code set up to send input to file.php and execute a query on every keyup event. When file.php echoes the result, it looks somet ...

Tips for implementing personalized command buttons in Kendo Grid with AJAX request utilizing JavaScript

I am struggling with implementing custom command buttons in a Kendo grid that makes an AJAX call using JavaScript to call a web API post action with dynamic parameters (start, stop, restart) behind button clicks. datasource dataSource = new ken ...

The AngularJS factory does not hold on to its value

I have developed a basic factory to store a value from my authService: app.factory("subfactory", function() { var subValue = {}; return { set: set, get: get }; functi ...

Tips for selecting a dropdown item that shares the same data-testid

I am attempting to use Selenium to click on an option in a dropdown menu. The options all have the same 'data-testid', and the only unique identifier appears to be the link text. Does anyone know of a way to select a specific choice within the dr ...

Switching image sources using jQuery on click

Take a look at the code snippet I've assembled below: $('img').on({ 'click': function() { var src = ($(this).attr('src') === 'memes/2a.png') ? 'memes/2b.png' : ...

Utilize ethereumjs-wallet in your web browser as a standalone module

I am looking to generate a wallet (which includes creating an account address and private key) directly in the browser without the need to connect to a node. It seems that in order to utilize web3.js, a provider (such as Metamask or localnode) needs to be ...

Invoking a synchronous JavaScript request to an MVC 4 Controller function

For the code I'm working on, I need certain functions to be executed sequentially. I attempted to use ajax calls but ran into issues due to their asynchronous nature. function GetLibraryActivities(libraryName, callback) { $.ajax({ dataTyp ...

Using JSON parsing to dynamically create classes with preloaded background images

Today, I successfully deployed my browser game using MVC4 to my website for the first time. I am currently navigating through the differences between running the site off of localhost and running it from the actual website. My process involves loading all ...

Unusual margin that demands attention!

I'm currently in the process of designing a website and have just started working on the header section. However, I've encountered an issue where there is an unexpected 28px margin at the top. Upon inspecting the code, I found the culprit: medi ...

When using `npm list`, the `create-react-app` package does not appear in the list of installed packages

I have a question that might be simple, but I couldn't find the answer anywhere. I've installed create-react-app using npm, but when I check with npm list it doesn't show up. What command can I use to see everything I've installed using ...

Upon clicking a button, initiate an Ajax call to retrieve a value from the code behind (aspx.cs) and display it in an input field on the same page

I am a beginner in the world of AJAX and encountering a problem. I need to initiate an AJAX call when a button is clicked. The goal is to send the value of an input field to the code behind page, aspx.cs, and then display the response from that same input ...

Prevent my buttons from altering their color when hovered over

I have created some visually appealing buttons that I am satisfied with, but when a user clicks on one, the text color changes and the button's hover behavior is altered. I utilized this generator to design the buttons: Below is the CSS code for my b ...