addy
addy

Reputation: 83

× TypeError: Cannot read property 'data' of undefined

React Hook useEffect has missing dependencies. Either include them or remove the dependency array, I'm new to react-redux and working on this small project, I'm getting this error, I tried adding generatePopupVariation and generatePopupOption to the dependency array but doesn't work. Please help me solve this error. Thanks in advance.

import React, { Fragment, useContext, useState, useEffect} from 'react'
import './Sass/Index.scss'
import { WishListContext } from '../../contexts/WishListContext'
import { ProductContext } from '../../contexts/ProductContext'
import Popup from "reactjs-popup";

const Product = ({product, id, productIndex}) => {
    const{name, price, image, variation, option, unit, total} = product
    const {wishListState, wishListDispatch} = useContext(WishListContext)
    const {productState} = useContext(ProductContext)
    const [popupVariation, setPopupVariation] = useState(false)
    const [popupOption, setPopupOption] = useState(false)
    const [listVariations, setListVariations] = useState([])
    const [listOptions, setListOptions] = useState([])
    const [selectedOption, setSelectedOption] = useState({})
    const [updateToggle, setUpdateToggle] = useState(false)
   

    useEffect(()=> {
        generatePopupVariation()
        generatePopupOptions()
    }, [productState])

    const updateLocalStorage = (products) => {
        if (products.length > 0) {
            wishListDispatch({
                type:"REPLACE_WISH",
                payload: products.map(item => item)
            })
        } 
    }

    const generatePopupOptions = () => {
        const products = productState.products
        if (products.length > 0) {
            const finedProduct = products.find(item => item.id === id)
            const priceOptions = finedProduct.data.priceOptions
            setListOptions(priceOptions[0].options)
        }
    }

    const generatePopupOptionContent= () => {
        if ( listOptions.length > 0 ) {
           const filtered = listOptions.filter(item => item.is_available !== 'No')
           return filtered.map((item, index) => <li key={index}><span>{item.option}</span><span>Price: {item.price}</span><div className="btn btn-primary" onClick={() => changeOption(index, item.option, item.price)} >Select</div></li>)
        }
    }

    const changeOption = (index, option, price) => {
        const action = {
            id,
            option,
            price
        }
        if (option) {
            wishListDispatch({
                type:'UPDATE_OPTION_WISH',
                action
            })
            updateLocalStorage(wishListState.products)
            modalOption('close')
        }  
    }

    const generatePopupVariation = () => {
        const products = productState.products
        if (products.length > 0) {
            const finedProduct = products.find(item => item.id === id)
            const priceOptions = finedProduct.data.priceOptions
            setListVariations(priceOptions)
        }
    }

    const generatePopupVariationContent = () => {
        if ( listVariations.length > 0 ) {
           return listVariations.map((item, index) => <li className="btn btn-primary" onClick={() => changeVariation(index, item.variation, item.options)} key={index}>{item.variation}</li>)
        }
    }

    const changeVariation = (index, variation, options) => {
        const action = {
            id,
            variation
        }
        if (variation) {
            wishListDispatch({
                type:'UPDATE_VARIATION_WISH',
                action
            })
            updateLocalStorage(wishListState.products)
            modalVariation('close')
        }  
    }
    
    const handleRemove = () => {
        if (wishListState) {
            if( wishListState.products.length > 0) {
                wishListDispatch({
                    type: 'REMOVE_WISH',
                    payload: productIndex
                })
            }
        }
    }
    const handleUnit = (control) => {
        if (wishListState) {
            if( wishListState.products.length > 0) {
                wishListDispatch({
                    type: 'ADD_UNIT_WISH',
                    payload: {index: productIndex, control:control}
                })
            }
        }
    }
    const modalVariation = action => {
        if (action === 'open') {
            setPopupVariation(true)
        } else if (action === 'close') {
            setPopupVariation(false)
        }
    }
    const modalOption = action => {
        if (action === 'open') {
            setPopupOption(true)
        } else if (action === 'close') {
            setPopupOption(false)
        }
    }

    return (
        <Fragment>
            <Popup
                open={popupVariation}
                closeOnDocumentClick
                onClose={()=> modalVariation('close')}
            >
                <div className="popup-content"> 
                    <ul>
                        {generatePopupVariationContent()}
                    </ul>
                    <span onClick={() => modalVariation('close')}>X</span>
                </div>
            </Popup>
            <Popup
                open={popupOption}
                closeOnDocumentClick
                onClose={()=> modalOption('close')}
            >
                <div className="popup-content"> 
                    <ul>
                        {generatePopupOptionContent()}
                    </ul>
                    <span onClick={() => modalOption('close')}>X</span>
                </div>
            </Popup>
                <div className="card">
                    <div className="card-wrapper">
                        <div className="left">
                            <img className="card-img" src={ image } alt={ name } />
                        </div>
                        <div className="right">
                            <div className="card-remove" onClick={handleRemove}>
                                <i className="times" name="close"></i>
                            </div>
                            <h4 className="card-title">{ name }</h4>
                            { variation && <p className="card-variation"><span>Variation:</span><span>{variation} <span onClick={()=> modalVariation('open')} className="change-variation"><ion-icon name="create"></ion-icon></span></span> </p>}
                            { option && <p className="card-option"><span>Option:</span><span> { option }  <span onClick={()=> modalOption('open')} className="change-option"><ion-icon name="create"></ion-icon></span></span></p>}
                            <div className="card-unit"><span>Qty:</span>
                                <div className="card-units-wrapper">
                                    <i className="plus" name="add" onClick={() => handleUnit('+')}></i>
                                    <div className="card-units">{unit}</div>
                                    <i className="minus" name="remove" onClick={() => handleUnit('-')}></i>
                                </div>
                            </div>
                            <p className="card-price"><span>Price:</span><span> {price} </span></p>
                            <p className="card-total"><span>Total:</span> <span>{total} </span></p>
                        </div>
                    </div>
                </div>
        </Fragment>
    )
}

export default Product

 const products = productState.products
  67 |     if (products.length > 0) {
  68 |         const finedProduct = products.find(item => item.id === id)
> 69 |         const priceOptions = finedProduct.data.priceOptions
     | ^  70 |         setListVariations(priceOptions)
  71 |     }
  72 | }

Upvotes: 0

Views: 433

Answers (1)

Otac&#237;lio Maia
Otac&#237;lio Maia

Reputation: 319

It happens because because priceOptions is empty, it happened because find didn't find the item you want or because the products list is empty.

You can solve this breaking problem using Optional chaining changing this line to:

const priceOptions = finedProduct?.data.priceOptions

But keep in mind that priceOptions can be null after this operation.

Upvotes: 1

Related Questions