1

I'm trying to get Bitcoin Price from Coindesk API. This is my app:

import React from 'react';
import ReactDOM from 'react-dom';

let bpiURL = 'http://api.coindesk.com/v1/bpi/currentprice.json';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: {}
        };
    }

    componentDidMount() {
        fetch(bpiURL)
            .then(response => response.json())
            .then(res => {
                console.log(res);
                return res;
            })
            .then(response => this.setState({ data: response }));
    }

    render() {
        return (
            <div>
                <p>
                    {this.state.data.disclaimer}
                </p>
            </div>
        );
    }
}

ReactDOM.render(<App />, document.getElementById('root'));
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

The problem is that it works with this.state.data.disclaimer and this.state.data.chartName but it doesn't work with this.state.data.bpi.USD.rate which is what I need. How can I get that value?

EDIT: this is what I get from this.state.data :

Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead. in p (at index.js:42) in div (at index.js:37) in App (at index.js:49)

4
  • 1
    Can you post the output of this.state.data ? Commented Jul 25, 2018 at 11:36
  • @LegenJerry Updated the question with this.state.data Commented Jul 25, 2018 at 11:41
  • @Ehsan You could console.log(this.state.data) instead of returning it in render for debugging purposes. Commented Jul 25, 2018 at 11:42
  • Sorry about that. formatting the output shows it does have rate property under USD. Commented Jul 25, 2018 at 11:46

2 Answers 2

2

this.state.data.bpi.USD.rate works, but only once the request has completed. Before that this.state.data.bpi will give undefined, and trying to access USD on that will give rise to an error.

You could change your default data to null, and check if data is set before you use it in the render method.

Example

let bpiURL = "https://api.coindesk.com/v1/bpi/currentprice.json";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
  }

  componentDidMount() {
    fetch(bpiURL)
      .then(response => response.json())
      .then(response => this.setState({ data: response }));
  }

  render() {
    return (
      <div>
        <p>{this.state.data && this.state.data.bpi.USD.rate}</p>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

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

Comments

0

import React, {Component} from 'react';


const bpiURL = "https://api.coindesk.com/v1/bpi/currentprice.json";

class App extends Component {
    // you should check component life cycle to prevent updating from fetch when component is unmounted
    _isMounted = false;
    state = {
        data: null,
        error: null

    };

    componentDidMount() {

        this._isMounted = true;
        fetch(bpiURL)
            .then(response => response.json())

            .then(response => this._isMounted && this.setState({data: response}))
            // introduce an error catch
            .catch(error => this._isMounted && this.setState({error}))
    }

    componentWillUnmount() {
        this._isMounted = false;
    }


    render() {
        const {data, error} = this.state;
        return (
            <div className="App">
                {/* optional : you could show the error message */}
                <p> {`USD rate :  ${ (data && data.bpi.USD.rate) || error }`}</p>
            </div>
        );
    }
}

export default App;

1 Comment

Maybe it is also recommended to use a library like 'axios' instead of native fetch

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.