I am creating my first mobile app using react-native. I am using axios to fetch data from a wordpress website.
I managed to successfully get data from an array JSON with a list of musical tracks. I then inserted data into a state
variable. Then, I used .map
function to show contents on screen. Here's a working sample code:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
export default class FreshTracks extends Component {
state={tracks:[]}
componentDidMount(){
axios.get("https://<URL for JSON list of tracks>")
.then(response => this.setState({tracks:response.data}))
.catch(function(error) {
console.log('Fetch error: ' + error.message);
});
}
renderTracks(){
return this.state.tracks.map (track =>
<View key={track.id}>
<Text>{track.title.rendered}</Text>
<Text>{track.content.rendered}</Text>
</View>
)
}
render() {
return (
<View>
{this.renderTracks()}
</View>
);
}
}
Now, I am struggling to get data from a single object JSON, one musical track.
At first, I tried keeping the same code, only changing the url. I get Fetch error: this.state.tracks.map is not a function
. I tried console.log(this.state.tracks)
before the return
in renderTracks()
and the data is returned in the console as an object, exactly how it should.
I then tried to change the state
initialization to: state={tracks:*{}*}
instead of state={tracks:*[]*}
. Also, i changed the renderTracks()
function to:
renderTracks(){
return (
<View>
<Text>{this.state.tracks.id}</Text>
<Text>{this.state.tracks.slug}</Text>
<Text>{this.state.tracks.title.rendered}</Text>
<Text>{this.state.tracks.content.rendered}</Text>
</View>
)
}
This way is partially working Accessing data on a single level like this.state.tracks.id
or this.state.tracks.slug
is working as expected. Accessing multi-level data like this.state.tracks.title.rendered
throws an error:
Cannot read property 'rendered' of undefined
What should I do to correctly get data from single object JSON?
A JSON object doesn't have a map()
method. So your code that assumed this.state.tracks
is an array would crash.
Instead, you want to keep this.state.track
as null
at first, and then fill it in with an object. Don't forget to check for null
in render and show some kind of a placeholder.
Something like this will probably work?
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
export default class FreshTracks extends Component {
state = {track: null};
componentDidMount(){
axios.get("https://<your URL for a single track>")
.then(response => this.setState({track:response.data}))
.catch(function(error) {
console.log('Fetch error: ' + error.message);
});
}
render() {
const track = this.state.track;
if (track === null) {
return <View><Text>Loading...</Text></View>;
}
return (
<View>
<Text>{track.title.rendered}</Text>
<Text>{track.content.rendered}</Text>
</View>
);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.