2

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

2
  • try dataC.General.H1Text instead of dataC.Data.General.H1Text Commented Aug 8, 2017 at 14:12
  • what do you get when you do console.log(this.state.dataC) just to see the structure. Commented Aug 8, 2017 at 14:14

4 Answers 4

1

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.

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

Comments

0

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.

Comments

0

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

Comments

0

Use optional chaining :

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

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.