1

I'm having a bit of a weird issue with a React project I've been working on. It is a basic Maths Game where users have to enter and submit their answer.

Most of the time, the game works as intended, but sometimes the game won't progress and I see a

Uncaught SyntaxError: Unexpected identifier

in the console. Investigating this, it points to the line in my JS that reads:

"let correctAnswer = eval(`${num1} ${sign} ${num2}`);"

I cannot see anything immediately wrong with this line and I've tried stepping through the functions involved to try and catch anything suspicious, but no luck.

I know this kind of error usually points towards a typo, but I haven't noticed any missing semicolons or brackets. Furthermore, after clicking a few times, I can get the game running again as normal.

How can a Uncaught SyntaxError be temporary?

I will post my code here, but with the Codepen linked you can see the behaviour I'm talking about. Codepen: https://codepen.io/augs0/pen/MWwXGNd?editors=0010

class App extends React.Component {
    state = {
      name: undefined,
      num1: undefined,
      sign: undefined,
      num2: undefined,
      isWrong: false,
      correctAnswer: undefined,
      answer: undefined,
      score: 0,
      user: undefined
    };

    componentDidMount = () => {
      this.setState(() => {
        this.createQuestion();
      });
    };

    updateName = (e) => {
      this.setState({
        name: e.target.value
      });
    };

    startGame = (e) => {
      const { name, score } = this.state;
      // deal with blank entry
      if (!name) return;

      //create object for new user to access this info for the current player
      const newUser = {
        score: 0,
        name
      };

      this.setState({
        user: newUser
      });
    };

    getAnswer = (e) => {
      this.setState({
        // what does this plus actually do?
        answer: +e.target.value
      });
    };

    clearField = () => {
      document.getElementById('form').reset();
    }

    checkAnswer = (e) => {
      e.preventDefault();
      const { correctAnswer, answer, score } = this.state;
      let newScore = undefined;
      if (correctAnswer === answer) {
        newScore = score + 1;
        this.clearField();
        this.createQuestion();
        this.setState({
          score: newScore,
          isWrong: false
        });
      } else {
        console.log(correctAnswer);
        newScore = score - 1;
        this.setState({
          score: newScore,
          isWrong: true
        });
      }
    };

    getRandomNumber = (size = 1) => {
      const minNr = 1;
      // Fill replaces the data in the array
      const maxNr = +Array(size).fill(9).join("");
      // +1 allows us to reach beyond 10 with Math.random
      const nr = Math.floor(Math.random() * (maxNr - minNr + 1) + minNr);
      return nr;
    };

    getRandomSign = () => {
      const signs = ["x", "*", "/", "+"];
      const randomizer = Math.floor(Math.random() * signs.length);

      return signs[randomizer];
    };

    createQuestion = (size = 1) => {
      const num1 = this.getRandomNumber(size);
      const sign = this.getRandomSign();
      const num2 = this.getRandomNumber(size);
      let correctAnswer = eval(`${num1} ${sign} ${num2}`);

      if (
        Math.floor(correctAnswer) !== correctAnswer ||
        correctAnswer === Infinity //prevent questions where the answer is a decimal or infinity
      ) {
        return this.createQuestion(size);
        // correctAnswer = Number(correctAnswer.toFixed(1)); 
      } else {
        this.setState({
          num1,
          sign,
          num2,
          correctAnswer
        });
        // this.checkScore()
      }
    };

    // checkScore = () => {
    //   const {name, score} = this.state;
    //   if(`${score} < 25`){
    //     console.log('Not yet!')
    //   }
    // }

    render() {
      const { name, num1, sign, num2, isWrong, score, user } = this.state;
      return (
        <>
          <h1>Maths game with React</h1>
          {user ? (
            <div>
              <h2>Hello, {name}</h2>
              <h2>Score: {score}</h2>
              <form id='form' onSubmit={this.checkAnswer}>
              <h2>Question:</h2>
              <div className="question">
                <p>{num1}</p>
                <p>{sign}</p>
                <p>{num2}</p>
                <p> = </p>
                <input
                  className={`answer ${isWrong && "wrong"}`}
                  type="number"
                  onChange={this.getAnswer}
                />
                <button onClick={this.checkAnswer}>Check answer</button>
              </div>
              </form>
              <div className="leaderboard">
                <h2>Leaderboard</h2>
                <p className="number-one">#1 The Maths Menace</p>
                <p className="score-one">100</p>
                <p className="number-two">#2 The Mean Average</p>
                <p className="score-two">50</p>
                <p className="number-three">#3 Here For Pi</p>{" "}
                <p className="score-three">25</p>
              </div>
            </div>
          ) : (
            <div>
              <p>
                Welcome to the Maths Game! Here you can practice your maths skills
                while trying to beat the high score.
              </p>
              <p>Please enter a username then click 'Start' to begin.</p>
              <input type="text" onChange={this.updateName} />
              <button className="btn" onClick={this.startGame}>
                Start
              </button>
            </div>
          )}
        </>
      );
    }
  }

  ReactDOM.render(<App />, document.getElementById("app"));
5
  • 1
    You are calling a setState in a setState via createQuestion without returning a value in the first setState? This is bound to get ugly. Commented Apr 3, 2020 at 10:17
  • what is the perpose of undefined :( name: undefined default is undefined Commented Apr 3, 2020 at 10:18
  • @xdeepakv this is probably just unnecessary code on my part, apologies for the confusion Commented Apr 3, 2020 at 10:34
  • @Gh05d I'm still learning React so it's not perfect. I would suggest that you don't just use commenting as an opportunity to take a passing swipe at somebody without much more to the comment. Thank you for commenting in any case. It's something I'll look into. Commented Apr 3, 2020 at 10:34
  • I was just shocked by the code. Did not mean any insult to you. Commented Apr 3, 2020 at 12:32

2 Answers 2

3

It looks like the problem occurs when "x" is selected from this array as x is not a valid arithmetic operator, but *, / and + are:

getRandomSign = () => { const signs = ["x", "*", "/", "+"];

I'm assuming that it was supposed to be a minus operator, in which case swapping it for a hyphen - should do the trick.

Example of when the error occurs:

Screenshot of code being evaluated in Chrome Dev Tools


Bonus:

// what does this plus actually do? answer: +e.target.value

I'm guessing the + operator is being used to cast the value to an integer. I've done a similar trick in the past but by adding - 0 to the end of a string.

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

2 Comments

Thank you! This did indeed solve the issue. Answer accepted.
you beat me to it: i added: console.log(`${num1} ${sign} ${num2}`) just before the error line: let correctAnswer = eval(`${num1} ${sign} ${num2}`); and saw the same :)
0

Ether one of these coming undefined:

let correctAnswer = eval(`${num1} ${sign} ${num2}`);

change it to

let correctAnswer = `${num1} ${sign} ${num2}`

eval(`${undefined} ${undefined} ${undefined}`) //Uncaught SyntaxError: Unexpected identifier

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.