javascript – How do I use this array of questions to create a quiz app?

I am creating a quiz app in React.

First, the data of questions needed to implement the app should be taken from this API:
const GET_QUIZ_API = `https://opentdb.com/api.phpamount=5&category=${categoryId}`;
The response looks like this:

{
"response_code": 0,
"results": [
{
"category": "Entertainment: Music",
"type": "multiple",
"difficulty": "medium",
"question": "Who had a 1973 hit with the song 'Hocus Pocus'?",
"correct_answer": "Focus",
"incorrect_answers": [
"Pilot",
"Rush",
"AC/DC"
]
},
{
"category": "Entertainment: Music",
"type": "multiple",
"difficulty": "easy",
"question": "What was the name of singer Frank Ocean's second studio album, which was released on August 20, 2016?",
"correct_answer": "Blonde",
"incorrect_answers": [
"Brunette",
"Black",
"Burgundy"
]
},
{
"category": "Entertainment: Music",
"type": "multiple",
"difficulty": "medium",
"question": "Which of the following guitarists recorded an album as a member of the Red Hot Chili Peppers?",
"correct_answer": "Dave Navarro",
"incorrect_answers": [
"Tom Morello ",
"Billy Corgan",
"Ed O'Brien"
]
},
{
"category": "Entertainment: Music",
"type": "multiple",
"difficulty": "medium",
"question": "The 'In the Flesh' tour was used in support of what Pink Floyd album?",
"correct_answer": "Animals",
"incorrect_answers": [
"The Wall",
"Wish You Were Here",
"The Final Cut"
]
},
{
"category": "Entertainment: Music",
"type": "multiple",
"difficulty": "easy",
"question": "What is the name of Rivers Cuomo's wife?",
"correct_answer": "Kyoko Ito",
"incorrect_answers": [
"Yoko Ono",
"Kyary Pamyu Pamyu",
"LiSA"
]
}
]
}

In the UI all the questions are displayed on the same page with answers below the questions. It looks like this:

How to use the above data to display answers in the buttons and verify them if correct later? After clicking the answer button it turns purple and with the CHECK ANSWERS button, the answers will be confirmed and the score will be calculated.

MY APPROACH: -> Collect all categories list and ids in the Start.js -> Get the questions array of the selected category id and add unique ids uid() in App.js -> Created new array of all the answers: with unique id for each answers to click the right button, with on value as false used to toggle on click, with the text as answer, with question id to which the answer belongs, in Game.js

App.js

import React from "react";
import { Start } from "./components/Start";
import { Game } from "./components/Game";
import { v4 as uuid } from "uuid";

export const App = () => {
  const [startScreen, setStartScreen] = React.useState(true);
  const [categoryId, setCategoryId] = React.useState();
  const [newQuestions, setNewQuestions] = React.useState([]);

  function startButtonClick(data) {
    setStartScreen(false);
    setCategoryId(data.categoryId);
  }
  const GET_QUIZ_API = `https://opentdb.com/api.php?amount=5&category=${categoryId}`;

  React.useEffect(() => {
    fetch(GET_QUIZ_API)
      .then((res) => res.json())
      .then((data) =>
        setNewQuestions(
          data.results.map((questions) => {
            return {
              ...questions,
              id: uuid(),
            };
          })
        )
      );
  }, [startScreen]);

  return (
    <div className="main">
      {startScreen ? (
        <Start startButtonClick={startButtonClick} />
      ) : (
        <Game newQuestions={newQuestions} />
      )}
    </div>
  );
};

Start.js

import React from "react";
import Skeleton from "react-loading-skeleton";
import "../../node_modules/react-loading-skeleton/dist/skeleton.css";

export const Start = (props) => {
  const [formData, setFormData] = React.useState({
    categoryId: "",
  });

  const [category, setCategory] = React.useState([]);

  const ALL_CATOGORY_API = "https://opentdb.com/api_category.php";

  React.useEffect(() => {
    fetch(ALL_CATOGORY_API)
      .then((res) => res.json())
      .then((data) => setCategory(data.trivia_categories));
  }, []);

  function handleChange(event) {
    const { name, value } = event.target;
    setFormData((prevData) => {
      return {
        ...prevData,
        [name]: value,
      };
    });
  }
  return (
    <div className="container">
      <div className="wrapper">
        <img className="top-bg" src="/top-background.png" alt="blobby top" />

        <img
          className="bottom-bg"
          src="/bottom-background.png"
          alt="blobby bottom"
        />
        <div className="body-contents">
          <div className="contents">
            <h1>Quizzical</h1>
            <p>The Quiz Game You Love</p>
          </div>
          <div className="dropdown">
            <label htmlFor="category-dropdown">Select Category</label>
            <br />
            <select
              id="category-dropdown"
              value={formData.categoryId}
              onChange={handleChange}
              name="categoryId"
            >
              {category.map((categories) => {
                return (
                  <option value={categories.id}>
                    {categories.name || <Skeleton count={1} />}
                  </option>
                );
              })}
            </select>
          </div>

          <div className="buttons">
            <button
              onClick={() => props.startButtonClick(formData)}
              type="button"
            >
              Start Quiz
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

Game.js

import React from "react";
import he from "he";
import { v4 as uuid } from "uuid";

// import { shuffle } from "../utils/shuffle";

export const Game = (props) => {
  //   let ansArray = [
  //     {
  //       question: "",
  //       answers: [],
  //     },
  //   ];

  let ansArray = [];

  let [clicked, setClicked] = React.useState([]);
  React.useEffect(() => {
    props.newQuestions.map((questions) => {
      let answers = [];
      questions.incorrect_answers.map((ans) => {
        answers.push({ ans: ans, index: uuid() });
      });
      let correct_answer = questions.correct_answer;
      answers.push({ ans: correct_answer, index: uuid() });

      answers.map((ans) => {
        ansArray.push({
          buttonId: ans.index,
          on: false,
          text: ans.ans,
          quesId: questions.id,
        });
      });
      setClicked(ansArray);
    });
  }, []);
  //   let ques = props.newQuestions.filter(function (e) {
  //     return clicked.map((answers) => {
  //       return e.id === answers.quesId;
  //     });
  //   });

  let quiz = clicked.map((answers) => {
    return (
      <div className="question-list">
        {/* <p>{he.decode(answers.question)}</p> */}
        <button
          key={answers.buttonId}
          type="button"
          value={answers.buttonId}
          id={answers.on ? "button-clicked" : ""}
          onClick={(event) => buttonClick(event)}
        >
          {he.decode(answers.text)}
        </button>
        <hr className="line" />
      </div>
    );
  });

  function buttonClick(event) {
    const { value } = event.target;

    setClicked((prevClick) => {
      return prevClick.map((a) => {
        return a.buttonId === value ? { ...a, on: !a.on } : a;
      });
    });
  }

  return (
    <div className="container">
      <div className="game-wrapper">
        <img className="top-bg" src="/top-background.png" alt="blobby top" />

        <img
          className="bottom-bg"
          src="/bottom-background.png"
          alt="blobby bottom"
        />

        {quiz}
      </div>
    </div>
  );
};

Leave a Comment