1

I've been having this issue for the past few hours now, and the only reason I'm posting a question so quickly is because there doesn't seen to be too much information on this topic, or at least this specific point.

I currently have a cloud function that grabs and saves data from a third-party API into my Firebase Firestore Database. In my frontend application I'm using React and attempting to display this data by mapping it to list Items. All high level items in the tree are fine to reach, and all the data from those is already displaying properly.

Any nested item though, returns with 'Cannot read property of undefined'. When console logging my top level container all subsequent data displays in the terminal. I can break it down all the way to the top level Array which shows me this structure:

Console Output for one of the Arrays returned from firebase

I need to access the keys within those objects, but as I mentioned earlier this is what I'm greeted with when I try to do so:

Uncaught TypeError: Cannot read property 'title' of undefined
    at ProductScreen (ProductScreen.js:56)

Also Here is the code from the current screen I'm working on, and how I am trying to access the data:

import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { detailsProduct } from '../actions/productActions';

const ProductScreen = (props) => {
    const [qty, setQty] = useState(1);
    const productDetails = useSelector(state => state.productDetails);
    const { product, loading, error } = productDetails;
    const resp = props.match.params.id;
    const dispatch = useDispatch();

    useEffect(() => {
        dispatch(detailsProduct(resp));
        return () => {
            //
        };
    }, []);

    const handelAddToCart = () => {
        props.history.push(`/cart/${resp}/?qty=${qty}`)
    }

    return <div>
        <div className='back-to-result'>
            <Link to='/'>Back to Results</Link>
        </div>
        {loading ? <div>Loading...</div> :
            error ? <div>{error}</div> :
                (
                    <div className='details'>
                        <div className='details-image'>
                            <img src={product.thumbnailImage //This ever comes through as well} alt='product'></img> 
                        </div>
                        <div className='details-info'>
                            <ul>
                                <li>
                                    <h4>{product.title}</h4> //This data comes through fine.
                                </li>
                                <li>
                                    {product.rating} Stars ({product.numReviews} Reviews)
                                </li>
                                <li>
                                    <b>{product.variants.price}</b>
                                </li>
                                <li>
                                    Description:
                                    <div>
                                        {product.description // This data comes through fine} 
                                    </div>
                                    <div>
                                        <select>
                                            {
                                            console.log(product.sizes.title // Here is where I am trying to console log the Size Title) 
                                            }

                                        </select>
                                    </div>
                                </li>
                            </ul>
                        </div>
                        <div className='details-action'>
                            <ul>
                                <li>
                                    <b>Price:</b> ${product.variants.price // This data does not come through either, has the same error} 
                                </li>
                                <li>
                                    Status: Currently Unavailable
                                </li>
                                <li>
                                    Qty: <select>
                                            <option>1</option>
                                            <option>2</option>
                                            <option>3</option>
                                            <option>4</option>
                                    </select>
                                </li>
                                <li>
                                    <button className='button' onClick={handelAddToCart}>Add to Cart</button>  
                                </li>
                            </ul>
                        </div>
                    </div>
                )
        }
    </div>
}

export default ProductScreen

I'm not sure where or what I'm doing wrong. Any help would be greatly appreciated. Thank you.

*Apologies for not including the main code initially, wasn't sure if it was going to be helpful If all I was doing was console logging, but I hop this is able to give a better perspective on the situation.

3
  • Could you please share some code example? Commented Jun 16, 2020 at 10:49
  • 1
    Please, both, code and errors should be shared in the properly format instead of using images. Commented Jun 16, 2020 at 13:28
  • @MaiKaYI have updated the post with new formatting and my code for the primary screen I'm working on right now. Commented Jun 16, 2020 at 20:14

1 Answer 1

1

I managed to figure out what was wrong, after many many console.logs I found a weird issue with how my data was entering my app. After a bit more research I found a Stackoverflow question on React state, and that's what my issue was. Inside my state control through Redux I only had my top level object with an initial state of {}, but what I discovered is that in the case of an object, you also need to set the initial state of any arrays within that object, and if you are returning objects inside those arrays you also need to set the state for those as well. This would end up looking like this:

state = { mainObj: { array: [], arrayWithObj: [{}]} }

And you would continue doing this for your whole data structure. This is all being done in my Redux reducer function. The only caveat to not have to do this, is if your top level item is an array, then you don't have to break down this structure, at least thats what I experienced on one of my other pages that had that.

I hope this helps anyone else with this issue.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.