State is null initially after using get request in componentDidMount

I have a react component where I want to get some data, using componentDidmount to get the data initially:

componentDidMount(){
axios.get('https://opentdb.com/api.php?amount=50').then( response =>{
for(var key in response.data.results){

    const question = [...this.state.question, response.data.results[key].question];
    const answer = [...this.state.answer, response.data.results[key].correct_answer];
    const wrongAnswers = [...this.state.wrongAnswers, response.data.results[key].incorrect_answers];
    this.setState( prevState => ({
        question: question,
        answer: answer,
        wrongAnswers: wrongAnswers
 }));    
 }
  });
 }

the problem is that I can't map the answers of wrongAnswers because they are undefined initially

  const {wrongAnswers} = this.state;
 {wrongAnswers[this.state.random] && this.state.wrongAnswers[this.state.random].map((wrongAnswer, index) => { //this does not display 
<p key={'Key-'+index}>here it is= {wrongAnswer}</p>
  })}

I tried making some checks to see when gets rendered what

 {this.state.wrongAnswers &&
console.log('the state is ' +this.state.wrongAnswers[this.state.random]);
} //this renders undefined initially, then renders an array of the right answers..

what is strange is that, if I just display the state, without performing any operations, it is displayed correctly.

  <p>{this.state.question[this.state.random]}</p> // displays the state correctly

  <p>{this.state.wrongAnswers[this.state.random]}</p> //displays the state correctly

I suspect, that I can't perform any operations, because it is not loaded initially, but since I put it in componentDidMount, you would suspect, that this problem would not occur?

EDIT:

whenever i put in the conditions for a simply parapragh

{this.state.random !== undefined && this.state.wrongAnswers[this.state.random] !== undefined &&

    <p> condition is met </p>

  }

it prints out

but when i map the array:

  {this.state.random !== undefined && this.state.wrongAnswers[this.state.random] !== undefined && this.state.wrongAnswers[this.state.random].map((wrongAnswer, index) => {
      console.log('inside the right method!'); //logs correctly three times like intended but does not print any jsx
    <p key={'Key-'+index}>here it is= {wrongAnswer}</p>

  })}

nothing is printed out.

Upvotes: 0

Views: 221

Answers (1)

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85545

You stated that <p>{this.state.wrongAnswers[this.state.random]}</p> works when placed inside the render hook. It means you will always get wrongAnswers ie. not undefined and invoking on wrongAnswers array of the state, there will be no error at initial render and it gets correct result at next render.

But using this code in componentDidMount hook,

{
  this.state.wrongAnswers &&
  console.log(this.state.wrongAnswers[this.state.random]);
}

At first time, it will obviously get the undefined because at that time this.state.random might be undefined or null and due to this reason, you will get undefined. For example:

const arr = [1,2,3]
console.log(arr[undefined]) // undefined
console.log(arr[null]) // undefined

Thus, I would suggest you to check the random state first and then use wrongAnswers with it:

{
  this.state.random &&
  console.log(this.state.wrongAnswers[this.state.random]);
}

The following will be unnecessary as wrongAnswers are not undefined at initial state as you stated. If you have not set wrongAnswers at initial state, then only the following is a way to do so:

{
  this.state.wrongAnswers &&
  this.state.random &&
  console.log(this.state.wrongAnswers[this.state.random]);
}

Sorry, I didn't figured out before your edit. But you need to use return statement while inside the map since you're using curly brace:

return <p>...</p>

You may also be interested to look in this post for further help, to know when to use return and when not to.

Upvotes: 1

Related Questions