Actually, I am new in react development and I want to show product page with it's summery but in JSON I have arrays of an object (maybe, shown in code). When I try to use .map I got an error like the prop is undefined.
I have JSON object like below
{
"id": 794,
"name": "Pellentesque habitant morbi",
"description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>\n",
"short_description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>\n",
"sku": "1000",
"price": "200",
"categories": [
{
"name": "Best Seller"
}
],
"regular_price": "21.99",
"tags": [
{"name" : "Books Online"},
{"name" : "Ebooks"},
],
"images": [
{
"src": "https://example.com/wp-content/uploads/2017/03/T_2_front-4.jpg",
},
{
"src": "https://example.com/wp-content/uploads/2017/03/T_2_back-2.jpg",
}
],
"author": "Mo. Ra. Walambe"
}
In my component render method, I am doing this
rendor(){
var tags = [];
const prodSum = this.props.product;
tags = prodSum.tags.map( (tag) => {
return <li>{tag.name}</li>;
});
return(
<h1 className="product_title">{prodSum.name}</h1>
<span className="posted_in">
Categories: <ul>{tags}</ul>
</span>
);
};
error is : prodSum.tags is undefined where I am able to show prodSum.name
Why it is not working with array.
I want to display the list of tags
As a blind suggestion as I do in my comment, you can conditionally render your component.
const product = {
id: "794",
name: "Pellentesque habitant morbi",
description:
"<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>\n",
short_description:
"<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>\n",
sku: "1000",
price: "200",
categories: [
{
name: "Best Seller"
}
],
regular_price: "21.99",
tags: [
{
name: "Books Online"
},
{
name: "Ebooks"
}
],
images: [
{
src: "https://example.com/wp-content/uploads/2017/03/T_2_front-4.jpg"
},
{
src: "https://example.com/wp-content/uploads/2017/03/T_2_back-2.jpg"
}
],
author: "Mo. Ra. Walambe"
};
function fakeApi() {
return new Promise(resolve => setTimeout(() => resolve(product), 2000));
}
class App extends React.Component {
state = {
product: null,
};
componentDidMount() {
fakeApi().then(product => this.setState({ product }));
}
render() {
return (
<div>
<Product product={this.state.product} />
</div>
);
}
}
function Product(props) {
const { product } = props;
if (!product) return <div>Getting the product...</div>;
const tags = product.tags.map(tag => {
return <li>{tag.name}</li>;
});
return (
<div>
<h1 className="product_title">{product.name}</h1>
<span className="posted_in">
Categories: <ul>{tags}</ul>
</span>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />
Do not think about the fakeApi
part, I'm just simulating the fetch part there. I'm not sure how do you initialize the product
state in the parent component but as you can see I'm doing it as null
. So I can check its existence in the child component. If no product
yet I'm rendering a piece of temporary information. After fetching the product child component is rerendered and return the product information.
As you can see in the comments there can be other scenarios. For example, you can set the initial state to {}
and check for its properties' existence, like tags
or set them to empty values like []
for the first render.
Using conditional rendering is common usage. React can deal with undefined
values, there isn't any problem with that. This is why prodSum.name
is not a problem, since it is undefined
. But Javascript can't deal something like undefined.someValue
. Because you are trying to get someValue
from undefined
and this is not possible. prodSum.tags[0].name
is undefined.name
here.