0

I have been trying to refactor code from data being set manually to mapping through a JSON file, more specifically translations using i18next.

Here is what the code looked like:

constructor(props) {
    super(props)
    var p1 = <Product
        img={ImageTruth}
        position={0}
        title={'title'}
        text={'text'}
        isBought={false}
        id={1}
        handleRemove={this.handleRemove}
    />
    var p2 = <Product
        img={ImageLies}
        position={3}
        title={'title'}
        text={text'}
        isBought={false}
        id={2}
        handleRemove={this.handleRemove}
    />
    var p3 = ...

    products.push (p1, p2, p3, p4, p5, p6)

    var selectedProduct = p1

    this.state = {
        products: products,
        selectedProduct: selectedProduct,
        bought: [],

        touchStartX: null,
        touchEndX: null,
        isOpen: false,
    }

Here is what I replaced it with:

// pulling Object from translations
var products_t = t('pulsesInfos', { ns: 'cards', returnObjects: true })

if (Object.values(products_t)[0]['text'] !== undefined) {

    // mapping through translations array of Objects
    Object.values(products_t).map(productItem => {
        const img1 = require('../img/pulses/' + productItem.image)
        const product = (
            <Product
                img={img1}
                position={0}
                title={productItem.title}
                text={productItem.text}
                isBought={false}
                id={productItem.id}
                handleRemove={this.handleRemove}
            />
        )
        // adding to the array for render
        products.push(product)
        
        if( productItem.id == 1 ){
            this.state = { selectedProduct: product }
            // setting selectedProduct with currrent one in loop if id=1
        }
    })
}

    this.state = {
        products: products,
        selectedProduct: selectedProduct, // when leaving this line, right side argument shows undefined
        bought: [],

        touchStartX: null,
        touchEndX: null,
        isOpen: false,
    }

However it returns: 'Failed to Compile' : selectedProduct is undefined.

For context, there are controls (left and right) that allows user to changer selectedProduct and Add it to Cart.

Is it a mistake of scope? or something else I'm missing? Thanks.

1 Answers1

-1

It seems like the issue you're encountering is related to the scope and order of operations. In your refactored code, you are trying to use the selectedProduct variable before it has been defined. The error message "selectedProduct is undefined" is a clear indication of this problem.

To resolve this, you need to make sure that the selectedProduct variable is properly defined before you use it in the state initialization. Here's how you can do that:

// pulling Object from translations
var products_t = t('pulsesInfos', { ns: 'cards', returnObjects: true });

// Define the variables outside the loop
var products = [];
var selectedProduct = null; // Initialize with null

if (Object.values(products_t)[0]['text'] !== undefined) {
    // Mapping through translations array of Objects
    Object.values(products_t).map(productItem => {
        const img1 = require('../img/pulses/' + productItem.image);
        const product = (
            <Product
                img={img1}
                position={0}
                title={productItem.title}
                text={productItem.text}
                isBought={false}
                id={productItem.id}
                handleRemove={this.handleRemove}
            />
        );
        products.push(product);

        if (productItem.id === 1) {
            selectedProduct = product; // Set the selectedProduct variable
        }
    });
}

// Now define the state after the loop
this.state = {
    products: products,
    selectedProduct: selectedProduct,
    bought: [],
    touchStartX: null,
    touchEndX: null,
    isOpen: false,
};


In this code, I've moved the definition of the products array and the selectedProduct variable outside of the loop. This ensures that the selectedProduct variable is defined properly before you use it in the state initialization. This should resolve the "selectedProduct is undefined" issue you were facing.

Ugur Tas
  • 216
  • 1
  • 9
  • Thank you very much! This indeed solved the issue! In parallel, I've noticed the component translations do not update on languageChange although I have wrapped it in a withTranslation HOC, contrary to all other components. Is there a way to re-render the component on languageChange? – Jonathan Buso Aug 21 '23 at 15:08