Reputation: 4055
I am having troubles trying to output my errors in react. the data is coming from an external API, and is formatted like so;
{
"message": "The given data was invalid.",
"errors": {
"name": [
"The name field is required."
],
"address": [
"The address field is required."
],
"postcode": [
"The postcode field is required."
]
}
}
My page which returns the API data and the error component looks something like this;
const ShowData = () => {
const [errorData, setErrorData] = useState([]);
const onSubmit = handleSubmit(async ({ name, address, postcode }) => {
if (errorData) setErrorData([]);
try {
// Call API and process here
} catch (error) {
setErrorData(error.data);
}
});
return (
<div>
{errorData && !Object.keys(errorData).length == 0 &&
<ErrorComponent errorData={errorData} />
}
</div>
)
}
export default ShowData;
class ErrorComponent extends Component {
render() {
const errorData = this.props.errorData;
return (
<div>{errorData.message}</div>
<ul>
{errorData.errors.map(error => {
<li>{error}</li>
})}
</ul>
)
}
}
export default ErrorComponent;
The error i am receiving is;
errorData.errors.map is not a function
The following is what i am trying to achieve;
<div>The given data was invalid.</div>
<ul>
<li>The name field is required.</li>
<li>The address field is required.</li>
<li>The postcode field is required.</li>
</ul>
Upvotes: 1
Views: 750
Reputation: 14891
First, you cannot use map
on objects, because map
itself is a method of Array
. As you can see in the doc, it is Array.prototype.map
. So here you could transform the errors to array before mapping. Here I use Object.entries
because I also want to display the field that caused error.
There are others problems rather than just iterating the errorData:
div
and ul
. you must wrap it into one element only. You could use div
to wrap, but I prefer using React.Fragment
undefined
, which would display nothing. Solution here is to use explicit return
, or shorthand with () => (<yourelement />)
class ErrorComponent extends React.Component {
render() {
const errorData = this.props.errorData;
return (
<React.Fragment>
<div>{errorData.message}</div>
<ul>
{Object.entries(errorData.errors).map(
([errorField, errorMessages]) => (
<li>
{errorField}: {errorMessages[0]}
</li>
)
)}
</ul>
</React.Fragment>
);
}
}
Live demo:
Upvotes: 1
Reputation: 7915
2 problems.
<ul>
{Object.values(errorData.errors).map((e, i) =>
<li key={i}>{e[0]}</li>
)}
</ul>
map
function is missing the return
statement, which you can include implicitly by dropping those curly braces as shown above.Upvotes: 2
Reputation: 112
You're trying to run .map() on an object. .map() is only usable on iterables.
You might try creating an array from the object using Object.keys, Object.values, Object.entries, or another method that creates an array from an object.
Upvotes: 1