skip to Main Content
const Productabout = () => {


const params = useParams();
const [singleProduct, setsingleProduct] = useState()
const host = "http://localhost:5000"


useEffect(() => {
    if (params.id) {
        getproduct()
    }
}, [params.id])

console.log(singleProduct.name);

getting error like Cannot read properties of undefined (reading ‘name’)

2

Answers


  1. This is practically a situtation where a loading element should be rendered first, until your asynchronous getProduct function fetches the product from the API and sets your singleProduct state to it.

    Here is a very simplified version of how you could implement that. Many other implementations can be done:

    1. Set a default value for singleProduct. In this case, I’m setting it to undefined.

      const [singleProduct, setsingleProduct] = useState(undefined);
      
    2. Now, we can check for the value of singleProduct. If it’s undefined, that means that the getProduct function did not finish executing yet and that we should display a loading element instead. When it’s finished executing, the value of singleProduct would change from undefined to some object like { "name": "hello world" }. In that case we can safely display the product:

      return singleProduct ? <p>{singleProduct.name}</p> : <p>loading...</p>;
      // The code above is equivalent to:
      if (singleProduct)
      {
          return <p>{singleProduct.name}</p>;
      }
      else
      {
          return <p>loading...</p>;
      }
      
    Login or Signup to reply.
  2. At the first render, the singleProduct is set to undefined.

    const [singleProduct, setsingleProduct] = useState()
    

    So when the console.log(singleProduct.name) is called during the initial rendering, it will raise an error because it’s attempting to access the name property of undefined singleProduct.

    If you want to monitor the singleProduct state, simply use a useEffect block where you can log the name of singleProduct while it’s available.

    const Productabout = () => {
      ...
      const params = useParams();
      const [singleProduct, setsingleProduct] = useState()
      const host = "http://localhost:5000"
      ...
    
      useEffect(() => {
        if (params.id) {
          getproduct()
        }
      }, [params.id])
    
      useEffect(() => {
        if (singleProduct) {
          console.log(singleProduct.name)
        }
      }, [singleProduct])
      ...
    
    }
    

    Or, if you are too lazy to use useEffect, you can simply use something like this:

    const Productabout = () => {
      ...
      const params = useParams();
      const [singleProduct, setsingleProduct] = useState()
      const host = "http://localhost:5000"
      ...
    
      useEffect(() => {
        if (params.id) {
          getproduct()
        }
      }, [params.id])
    
      console.log(singleProduct && singleProduct.name || undefined);
      ...
    
    }
    

    or you can use the optional chaining operator (?.) if you are using ECMAScript 2020 (ES11).

      console.log(singleProduct?.name)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search