I am new to react and trying to work with last fm api, but I got problem working with json page. When I try:
class App extends React.Component <{}, {items: Array<String>, DataisLoaded: boolean}> {
constructor(props: any) {
super(props);
this.state = {
items: [],
DataisLoaded: false
};
}
componentDidMount() {
fetch("https://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks&api_key=6808816d086d4c48075217bd2cc178a1&format=json")
.then((res) => res.json())
.then((json) => {
this.setState({
items: json,
DataisLoaded: true
});
})
}
render() {
const { DataisLoaded, items } = this.state;
if (!DataisLoaded) return <div><h1>Pleses wait some time.... </h1></div>;
return (
<div className = "App">
<h1> Fetch data from an api in react </h1>
{Array.from(items).map((item: any) => (
<ol>
Name: { item.name },
</ol>
))}
</div>);
}
I got Uncaught Error: Invariant Violation: Objects are not valid as a React child (found: object with keys).
How to work with pages like that? How to map them? I tried several times, but don't understand. How to get name of the track and name of artist?
JSON page look like this:
{"tracks":{"track":[
{"name":"Bad Habit",
"duration":"0",
"playcount":"8259188",
"listeners":"539192",
"mbid":"",
"url":"https://www.last.fm/music/Steve Lacy/_/Bad Habit",
"streamable":{"#text":"0","fulltrack":"0"},
"artist":{"name":"Steve Lacy","mbid":"ca9766a0-1c30-43e6-a213-bac1334efc4a","url":"https://www.last.fm/music/Steve Lacy"},
"image":[{"#text":"https://lastfm.freetls.fastly.net/i/u/34s/2a96cbd8b46e442fc41c2b86b821562f.png","size":"small"},{"#text":"https://lastfm.freetls.fastly.net/i/u/64s/2a96cbd8b46e442fc41c2b86b821562f.png","size":"medium"},{"#text":"https://lastfm.freetls.fastly.net/i/u/174s/2a96cbd8b46e442fc41c2b86b821562f.png","size":"large"},{"#text":"https://lastfm.freetls.fastly.net/i/u/300x300/2a96cbd8b46e442fc41c2b86b821562f.png","size":"extralarge"}]}
}
],"@attr":{"page":"1","perPage":"50","totalPages":"626758","total":"31337870"}}}
CodePudding user response:
The problem here you're mapping through tracks and @attr which are objects. what you want to do is reach the track inside tracks and map that
items.tracks.track.map
so what you should do is the following after you fetch do
this.setState({
items: json.tracks.track,
DataisLoaded: true
});
and then
{items.map((item: any) => (
<ol>
Name: { item.name },
</ol>
))}