Reputation: 575
I'm writing a React App that gets JSON data from an API and shows some of it's contents.
This is the data it gets:
{"id":6,"name":"5 Storey I=0.7","Value":1344981250,"NSt":5,"jRatio":"[0.2,0.4,0.4]","jEDR":"[0.02,0.1,0.5,1]"}
And this is the App:
class App extends React.Component{
constructor(props){
super(props);
this.state={
data: [],
isLoading: false,
error: null,
};
}
componentDidMount(){
this.setState({isLoading: true});
axios.get(API)
.then(response => console.log(response.data.Value))
.then(response => this.setState({data: response.data, isLoading: false}))
.catch(response => this.setState({error: response.error, isLoading: false}));
}
render(){
return (
<div>
<p>{this.state.error}</p>
<p>{this.state.isLoading ? 'Loading...':'Loaded'}</p>
<ul>{this.state.data.Value.toString()}</ul>
</div>
)
}
}
<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>
I get the Value "1344981250" in console but the page throws this error:
TypeError: this.state.data.Value is undefined
and in console:
The development server has disconnected. Refresh the page if necessary.
I also tried this:
this.state.data.map(obj => <li key={obj.toString()}>{obj.toString()}</li>)
and this time without any error, nothing shows up on the page. (this one works for arrays of objects but shows nothing when it's just one object)
So what did I miss?
Upvotes: 2
Views: 113
Reputation: 104459
TypeError: this.state.data.Value is undefined
Because data is an array and [].Value
(any key) will be undefined.
Check this snippet:
let data = [];
console.log('data.Value = ', data.Value);
// this will throw error:
console.log('data.value.toString', data.Value.toString())
You defined the initial value of data as an array, and you are getting the object from api call. Solution is define the initial value as:
data: {}
And inside render method, write it like this:
<ul>{(this.state.data.Value || '').toString()}</ul>
You need to return the response from .then
:
axios.get(API)
.then(response => {console.log(response.data.Value); return response;} //<=== here
.then(response => this.setState({data: response.data, isLoading: false}))
.catch(response => this.setState({error: response.error, isLoading: false}))
Edit:
componentDidMount will get called after the initial rendering, so its better to define the initial value of isLoading: true
, after that you can remove this:
this.setState({isLoading: true});
Upvotes: 2