I am trying to fetch data from external source(springboot) and populate it to my class based react component in place of the dummy data. But I am getting an error which I am not clearly able to identify as to why this is thrown.
My api from springboot contains array of objects which looks like below:
[{"id":1,"question":"What is the capital of France","answer":"PARIS"},{"id":2,"question":"What is the capital of India","answer":"DELHI"},{"id":3,"question":"Excellent! Congratulations!","answer":"You Survived"}]
My React class looks like:
import React, { Component, useState } from 'react';
import Question from '../Question/Question';
import Keyboard from '../Keyboard/Keyboard';
import Puppet from '../Puppet/Puppet';
import GameStatus from '../GameStatus/GameStatus';
// import { questionsAndAnswers } from '../../gamedata';
import Confetti from 'react-confetti';
import './Game.css';
export class Game extends Component {
constructor(props) {
super(props);
this.state = {
questionsAndAnswers:[],
triggerConfetti: false,
gameCompleted: false,
gameAlive: true,
pressedLettersArray: [],
currOp: 0,
maxOps: 6,
questionNumber: 0,
keys: [
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'Ñ',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z'
]
};
}
async componentDidMount() {
fetch("http://localhost:8080/qna/all")
.then(result=>result.json())
.then((result)=>{
this.setState({questionsAndAnswers: result})
console.log("Recieved Details")
})
// const response = await fetch("http://localhost:8080/qna/all");
// const body = await response.json();
// console.log(body);
// this.setState({questionsAndAnswers: body});
if (this.state.gameCompleted === true) {
this.setState({
triggerConfetti: true
});
}
}
handlePressedLetter = letter => {
const pressedLettersArray = [...this.state.pressedLettersArray] || [];
const word = this.state.questionsAndAnswers[this.state.questionNumber].answer;
if (word.includes(letter)) {
this.setState({
pressedLettersArray: [...pressedLettersArray, letter]
});
} else {
this.setState({
currOp: this.state.currOp 1
});
if (this.state.currOp >= this.state.maxOps) {
this.setState({
gameAlive: false
});
}
}
};
resetGame = () => {
this.setState({
triggerConfetti: false,
gameCompleted: false,
gameAlive: true,
currOp: 0,
questionNumber: 0,
pressedLettersArray: []
});
};
componentDidUpdate = () => {
const wordLettersArr = this.state.questionsAndAnswers[this.state.questionNumber].answer.split('');
const keysPressedArr = this.state.pressedLettersArray;
const complete = wordLettersArr.every(letter => keysPressedArr.includes(letter));
if (complete) {
if (this.state.questionNumber < this.state.questionsAndAnswers.length - 2) {
this.setState({
pressedLettersArray: [],
currOp: 0,
questionNumber: this.state.questionNumber 1
});
} else if (
this.state.questionNumber === this.state.questionsAndAnswers.length - 2 &&
this.state.gameCompleted === false
) {
this.setState({
gameCompleted: true,
currOp: 0,
pressedLettersArray: this.state.questionsAndAnswers[this.state.questionNumber 1].answer.split(''),
questionNumber: this.state.questionNumber 1
});
}
}
if (this.state.gameCompleted === true && this.state.triggerConfetti === false) {
this.setState({
triggerConfetti: true
});
}
};
render() {
const word = (this.state.questionsAndAnswers[this.state.questionNumber] && this.state.questionsAndAnswers[this.state.questionNumber].answer);
return (
<div className="game">
{this.state.triggerConfetti ? (
<Confetti
height={document.querySelector('.game').offsetHeight}
width={document.querySelector('.game').offsetWidth}
/>
) : null}
<h2>Welcome</h2>
<Puppet
questionNumber={this.state.questionNumber}
currOp={this.state.currOp}
gameAlive={this.state.gameAlive}
qna={this.state.questionsAndAnswers}
/>
<Question
qna={this.state.questionsAndAnswers}
questionNum={this.state.questionNumber}
pressedLettersArray={this.state.pressedLettersArray}
gameAlive={this.state.gameAlive}
/>
<GameStatus
qna={this.state.questionsAndAnswers}
gameAlive={this.state.gameAlive}
resetGame={this.resetGame}
questionNumber={this.state.questionNumber}
gameCompleted={this.state.gameCompleted}
/>
<Keyboard
keys={this.state.keys}
handlePressedLetter={this.handlePressedLetter}
word={word}
gameAlive={this.state.gameAlive}
gameCompleted={this.state.gameCompleted}
/>
</div>
);
}
}
export default Game;
When I console log to see if I fetched the data correctly it shows me undefined, but when I am using useEffect in functional component using the same url, I am able to see the data. But lets not divert from the motive of using it in the class based component.
The Error looks like:Error SS
The error is shown in the question class which looks like:
import React from 'react'
import { useTransition, animated } from 'react-spring'
import Letter from '../Letter/Letter'
import './Question.css'
const Question = ({gameAlive, qna, questionNum, pressedLettersArray}) => {
const currentQ = qna[questionNum];
const transitions = useTransition(currentQ, currentQ => currentQ.answer, {
from: { opacity: 0, transform: 'translateX(100%)' },
enter: { opacity: 1, transform: 'translateX(0px)' },
leave: { opacity: 0, transform: 'translateX(-100%)' }
})
return (
transitions.map(({ item, key, props }) => (
<animated.div className={gameAlive ? "question" : "question gray"} key={key} style={props}>
<p>{item.question}</p>
<div className="guessing-word">
{item.answer.split("").map((singleLetter, index) => (
<Letter
key={`${index}${singleLetter}`}
singleLetter={singleLetter}
pressedLettersArray={pressedLettersArray}
/>
))}
</div>
</animated.div>
)
)
)
}
export default Question
I know its a long description but I tried to go through all the resource available but yet not able to spot what I am missing out. Please help me resolve this. Thanks in advance.
CodePudding user response:
result.json()
returns a promise. Therefore changing your fetch to this may help
fetch("http://localhost:8080/qna/all")
.then(result=>result.json().then((jsonResult)=>{
this.setState({questionsAndAnswers: jsonResult})
console.log("Recieved Details")
}))
I did not format the code properly because I want to highlight that .then()
needs to be chained to the json call. In your code you have ((result) => result.json()).then()
, so you need to remove the closing bracket )
and chain the .then()
to .json()
. Which would be ((result) => result.json().then(jsonRes => // do stuff))