Home > OS >  × TypeError: Cannot read properties of undefined (reading 'details')
× TypeError: Cannot read properties of undefined (reading 'details')

Time:07-13

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);
}
  • Related