0

I just started practicing on TypeScript and React and I don't know where I get wrong on this problem. They just kept telling me 'Cannot read Property 'map' of undefined'. Can someone tell me where I get wrong?

// Main files for application
import React,{useState} from 'react';
import {fetchQuizQuestions} from './API';
// Components
import QuestionCard from './components/QuestionCard';
// Types
import {QuestionState, Difficulty} from './API';

type AnswerObject = {
  question :string;
  answer :string;
  correct :boolean;
  correctAnswer :string;
}
const TOTAL_QUESTIONS = 10;

const App =() =>{
  const[loading,setLoading] = useState(false);
  const[questions,setQuestions] = useState<QuestionState[]>([]);
  const[number,setNumber] = useState(0);
  const[userAnswer,setUserAnswer] = useState<AnswerObject[]>([]);
  const[score,setScore] = useState(0);
  const[gameOver,setGameover] = useState(true);

  console.log(questions);

  const startTrivia = async () =>{
    setLoading(true);
    setGameover(false);

    const newQuestions = await fetchQuizQuestions(
      TOTAL_QUESTIONS,
      Difficulty.EASY
    );
      setQuestions(newQuestions);
      setScore(0);
      setUserAnswer([]);
      setNumber(0);
      setLoading(false);
  };
  const checkAnswer = (e: React.MouseEvent<HTMLButtonElement>)=>{

  }
  const nextQuestion=()=>{

  }
  return (<div className="App">Quiz
    <h1>REACT QUIZ</h1>
    {
      gameOver || userAnswer.length === TOTAL_QUESTIONS?(
    
    <button className="start" onClick={startTrivia}>
      Start
    </button>
      ):null}
    {!gameOver ? <p className="score">Score</p>: null}
    {loading ? <p>Loading Questions...</p> : null}
    {!loading && !gameOver &&(
    <QuestionCard
      questionNumber ={number + 1}
      totalQuestions = {TOTAL_QUESTIONS}
      question={questions[number].question}
      answers ={questions[number].answers}
      userAnswer = {userAnswer ? userAnswer[number]: undefined}
      callback={checkAnswer}
    />
    )}
    {!gameOver && 
    !loading && 
    userAnswer.length === number + 1 && 
    number !== TOTAL_QUESTIONS - 1 ? (
    <button className="next" onClick={nextQuestion}>
      Next Question
    </button>
    ):null }
  </div>
  );
}

export default App;

Here is another QuestionCard file that I have been working on. The console shows the problem is on 'answers.map'.

import React from 'react';

type Props ={
    question:string;
    answers:string[];
    callback:any;
    userAnswer:any;
    questionNumber : number;
    totalQuestions:number;
};
const QuestionCard:React.FC<Props>=({
    question,
    answers,
    callback,
    userAnswer,
    questionNumber,
    totalQuestions,
    })=>(
<div>
    <p className='number'>
        Question:{questionNumber} / {totalQuestions}
    </p>
    <p dangerouslySetInnerHTML={{ __html:question}}/>
    <div>
        {answers.map((answer)=>(
            <div key={answer}>
                <button disabled={userAnswer} onClick={callback}>
                    <span dangerouslySetInnerHTML={{ __html:answer}}/>
                </button>
            </div>
        ))}
    </div>
</div>
);

export default QuestionCard;

2
  • I assume "answers" does not have any values or is null. This is why you are probably getting that error Commented Aug 19, 2020 at 1:40
  • can u provide QuestionState content? Commented Aug 19, 2020 at 1:51

2 Answers 2

1

QuestionCard.jsx

<div>
   {/* make sure the `answers` exist */}
   {answers && answers.map((answer)=>(
       <div key={answer}>
          <button disabled={userAnswer} onClick={callback}>
             <span dangerouslySetInnerHTML={{ __html:answer}}/>
          </button>
       </div>
    ))}
</div>


Sign up to request clarification or add additional context in comments.

1 Comment

yes. actually when u got error like Cannot read property 'xxx' of undefined that always cuz the value of called the 'xxx' method is falsy value. maybe null or undefined. so u can't invoke an undefined or null value's method null.map() // invalid
0

Check that answers isn't undefined and take appropriate actions if it is

<div>
    {answers
        ? answers.map((answer)=>(
            <div key={answer}>
                <button disabled={userAnswer} onClick={callback}>
                    <span dangerouslySetInnerHTML={{ __html:answer}}/>
                </button>
            </div>
        ))
        : 'No answers!'
    }
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.