I am trying to open product details page onClick on the product card and when I go back from the browser I want to be able to click another product card with onClick leading to it's product detail page but I get this type error. "details" is an array, it could be empty at times but having a condition product['details'] to only render if it's true is ignored rather I get an error
const [ dataLoad, holdRender ] = useState(false); //hold render until data is ready
const [ product, setProduct ] = useState({});
const [ currentProduct, setCurrentProduct ] = useState(0);
//this useEffect runs once
useEffect(()=> {
(async () => {
//set params id received so whenever it updates the data is updated
const productId = await props.getProduct(props.match.params.id);
setCurrentProduct(productId);
})();
}, []);
//this useEffect runs everytime the params id is received/changed
useEffect(() => {
//get data from the backend to update UI in time until then hold
(async () => {
const data = await props.security.product.data;
setProduct(data);
})();
//if product.details is now available
if(product['details']){
//let go of render
holdRender(true);
}
else{
return null;
}
return () => {
setCurrentProduct(0);
};
}, [currentProduct]);
return(
<div>
{dataLoad !== false?
<div>
<Row>
<Col>
<Jumbotron id="productStatsCard">
<div className="productStats">
<h2>{product? product['details_not_verified']: <Loader/>}</h2>
</div>
</Jumbotron>
</Col>
<Col>
<Jumbotron id="productStatsCard">
<div className="productStats">
<h2>{product? product['details_verified']: <Loader />}</h2>
</div>
</Jumbotron>
</Col>
</Row>
<Row className="mt-5">
<Col sm={8}>
<Row>
<Col>
<div className="pdtTableContainer">
<div>
<Table>
<thead>
<tr>
<th>Category</th>
<th>Product Id</th>
<th>Product Name</th>
<th>Product Type</th>
</tr>
</thead>
<tbody>
{dataLoad && product['details']? product['details'].map(detail => (
<tr key={product.id}>
<td>
{product.category}
</td>
<td>{product.id}</td>
<td>
{product.product_title}
</td>
<td>{product.product_type}</td>
</tr>
)) : 'No products to display'}
</tbody>
</Table>
</div>
</div>
</Col>
</Row>
</Col>
</Row>
</div>: <Loader/>}
</div>
)
}
const mapStateToProps = (state) => ({
security: state.security,
});
export default connect(mapStateToProps, { getProduct })(productOverview);```
CodePudding user response:
Use the optional chaining operator:
if(product?.['details']){
//let go of render
holdRender(true);
}
By the way, you can access details
with the dot notation:
if(product?.details){
//let go of render
holdRender(true);
}