Reputation: 575
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)
Upvotes: 1
Views: 254
Reputation: 11
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;
Upvotes: 0
Reputation: 112777
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>
Upvotes: 2