Skip to content
Advertisement

Shuffling in react

I am fetching data from an api.Trying to make quiz application from the data of an API.I have selected random countries and their respective capitals and map them to my quiz application.I have achieved this already.Now i am trying to shuffle my answer options but not able to do that.anybody can please help? Here is my code

import React from "react";
import "./Quiz.css";
import { useState, useEffect } from "react";
function Quiz() {

    const [cname, scname] = useState([]);
  const [results, finalres] = useState(false);
  const [score, setScore] = useState(0);
  const [currentQues, setCurrentQues] = useState(0);
   //Get Method
   useEffect(() => {
    fetch("https://countriesnow.space/api/v0.1/countries/capital")
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        scname(data.data);
      });
  }, []);
//   const questions=[{},[{}]];
//   const questionText=Array.of(data.data.name)

//   const answerOptions=[{}];

const restartGame = () => {
    setScore(0);
    setCurrentQues(0);
    finalres(false);


  };
  let namearray = [5];
  var capitalArray = [5];

  let fx = (i) => {
    let countryName = "";
    let capitalName = "";
    let countryNum = Math.floor(Math.random() * cname.length);
    if (countryNum) {
      countryName = cname[countryNum].name;
      capitalName = cname[countryNum].capital;
      
    }
    namearray[i] = countryName;
    capitalArray[i] = capitalName;
  };

  for (let i = 0; i < 5; i++) {
    fx(i);
  }

// console.log(capitalArray.length)
// function shuffle(array) {
//     let currentIndex = array.length,  randomIndex;
  
//     // While there remain elements to shuffle.
//     while (currentIndex != 0) {
  
//       // Pick a remaining element.
//       randomIndex = Math.floor(Math.random() * currentIndex);
//       currentIndex--;
  
//       // And swap it with the current element.
//       [array[currentIndex], array[randomIndex]] = [
//         array[randomIndex], array[currentIndex]];
//     }
  
//     return array;
   
//   }


  
  const questions = [
    {
      questionText: "What is the capital of " + namearray[0] + "?",
      answerOptions: [
        { answerText: capitalArray[0], isCorrect: true },
        { answerText: capitalArray[1], isCorrect: false },
        { answerText: capitalArray[2], isCorrect: false },
        { answerText: capitalArray[3], isCorrect: false },
      ],
    },
    {
      questionText: "What is the capital of " + namearray[1] + "?",
      answerOptions: [
        { answerText: capitalArray[4], isCorrect: false },
        { answerText: capitalArray[1], isCorrect: true },
        { answerText: capitalArray[0], isCorrect: false },
        { answerText: capitalArray[3], isCorrect: false },
      ],
    },
    {
      questionText: "What is the capital of " + namearray[2] + "?",
      answerOptions: [
        { answerText: capitalArray[1], isCorrect: false },
        { answerText: capitalArray[0], isCorrect: false },
        { answerText: capitalArray[2], isCorrect: true },
        { answerText: capitalArray[3], isCorrect: false },
      ],
    },
    {
      questionText: "What is the capital of " + namearray[3] + "?",
      answerOptions: [
        { answerText: capitalArray[0], isCorrect: false },
        { answerText: capitalArray[2], isCorrect: false },
        { answerText: capitalArray[1], isCorrect: false },
        { answerText: capitalArray[3], isCorrect: true },
      ],
    },
    {
      questionText: "What is the capital of " + namearray[4] + "?",
      answerOptions: [
        { answerText: capitalArray[4], isCorrect: true },
        { answerText: capitalArray[1], isCorrect: false },
        { answerText: capitalArray[2], isCorrect: false },
        { answerText: capitalArray[3], isCorrect: false },
      ],
    },
  ];
  const hoc = (isCorrect) => {
    if (isCorrect === true) {
      setScore(score + 1);
    }
    const nextq = currentQues + 1;
    if (nextq < questions.length) {
      setCurrentQues(nextq);
    } else {
      finalres(true);
    }

  
  };

//   const shuffle = () => 0.5 - Math.random();

// const testQuestions = questions.map(q => ({
//   ...q,
//   // this one shuffles the answers...
  
//   answerOptions: q.answerOptions.sort(shuffle)
  
// })  
// )
 console.log('data')
  return (
    <>
      <h4>Quiz</h4>
      <div id="head">Welcome User</div>
      <hr />
      {results ? (
        <div className="final-res">
          Final Results
          <h4>you scored {score} out of 5</h4>
          <button onClick={() => restartGame()}>Restart</button>
        </div>
      ) : (
        <div>
          <div id="quescard">
            <h3>
              {currentQues + 1}. {questions[currentQues].questionText}
            </h3>
            {questions[currentQues].answerOptions.map((ansopt) => (
            
              <button onClick={() => hoc(ansopt.isCorrect)}>
                {ansopt.answerText}
              </button>
            ))}
          </div>
        </div>
      )}
    </>
  );
}

export default Quiz

I have applied shuffle function but not sure whether its working or not

Advertisement

Answer

you can shuffle an array as so having a function in the component function body as below

const shuffledAnswers = (currentQues) => {
  let shuffled = questions[currentQues].answerOptions
    .map((value) => ({ value, sort: Math.random() }))
    .sort((a, b) => a.sort - b.sort)
    .map(({ value }) => value);

  return shuffled;
};

and then in render you can invoke it as

{
  shuffledAnswers(currentQues).map((ansopt) => (
    <button onClick={() => hoc(ansopt.isCorrect)}>{ansopt.answerText}</button>
  ));
}

added the relevant code only to keep it simple … hope it works and is the expected result

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement