I am working on an assignment where I need to access data from an API. Most recently, I see that my code is working to retrieve the data… but when I try to loop over the data and display to my browser… I am getting the error:
Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {common, official, nativeName}). If you meant to render a collection of children, use an array instead.
I found similar questions on Stack Overflow… but they were using async/await and not fetch to retrieve their data.
Could someone please explain what I’m doing wrong here?
Code below:
import React, { Component } from "react";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
items: [],
isLoaded: false,
};
}
// fetches data and sets state which rerenders App
componentDidMount() {
fetch("https://restcountries.com/v3.1/all")
.then((res) => res.json())
.then((json) => {
this.setState({
isLoaded: true,
items: json,
});
});
}
render() {
var { isLoaded, items } = this.state;
if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div className="App">
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
;
</ul>
</div>
);
}
}
}
>Solution :
Actually the name property is also an object. Here’s an example of its content.
{common: 'Malta', official: 'Republic of Malta', nativeName: {…}}
In reactJS, you can’t render an object like that. You either convert it to a string using for example JSON.stringify(myobj) or extract the attributes you want.
In this case you should probably select what you want to display like for example:
render() {
var { isLoaded, items } = this.state;
if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div className="App">
<ul>
{items.map((item) => (
<li key={item.id}>{item.name.common}</li>
))}
;
</ul>
</div>
);
}
}
Also I noticed your api can handle internationalization, you can handle it in react using react-intl for example.