Aymen
Aymen

Reputation: 1496

Cannot read property object reactJS

I just have to extract the data

import React,{Component} from 'react';
import axios from 'axios';
import CoinsConvert from '../data/data'
import '../style/bootstrap.min.css';


class BoxInfo extends Component{

  constructor(){
    super();
    this.state={
      dataC:{}
    }

  }
  componentWillMount(){
        let code=CoinsConvert[this.props.match.params.coin_url];
        axios.get(`https://www.cryptocompare.com/api/data/coinsnapshotfullbyid/?id=${code}`)
        .then(da=>this.setState({dataC:da.data})).catch(()=>{console.error()})
  }
 render(){
   let dataC=this.state.dataC;
    return(
      <div className="container">
        <div className="panel panel-default text-center"  >
        <div className="panel-heading" >{ dataC.Data.General.H1Text}</div>
        <div className="panel-body "><img className="img-rounded"  width="500" height="500" src={""} /></div>
        </div>
      </div>
    );
   }
}

enter image description here

Example json: cryptocompare

Upvotes: 2

Views: 1718

Answers (4)

Alisha Irshad
Alisha Irshad

Reputation: 64

Use optional chaining :

const data = somevalue; console.log(data?.value);

Upvotes: 0

Mayank Shukla
Mayank Shukla

Reputation: 104379

Simple one, api calls are asynchronous so this.state.dataC will be {} until you get the api response.

During first rendering when you try to access:

this.state.dataC.Data it will be undefined and when you try to access any value of undefined it will throw the error:

Can't read property XYZ of undefined.

Solution:

Put the check on data, once you get the data then only render then ui.

Like this:

render(){

   let dataC=this.state.dataC;
   if(!Object.keys(dataC)) return null;

   return (
       ....
   )
}

You can also put the check on each value, Like this:

{ dataC.Data && dataC.Data.General && dataC.Data.General.H1Text}

Suggestion:

Instead of making the api call inside componentWillMount, write it inside componentDidMount.

Upvotes: 1

Sagiv b.g
Sagiv b.g

Reputation: 31024

First of all you should get async data only in componentDidMount method DOCS
Another thing that i think may cause a problem, with this line:

this.setState({dataC:da.data})

You actually already accessed the data property. In your render method you should do this:

dataC.General.H1Text

Instead of this:

dataC.Data.General.H1Text

Upvotes: 0

Amid
Amid

Reputation: 22352

Most likely the problem is due to the fact that you set dataC as a result of async data fetching. Therefore componentWillMount will complete, then render will be called, and note! - at this point the data might not still be fetched - so in render your dataC is undefined.

Upvotes: 0

Related Questions