Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React Redux – Cannot set properties of undefined (setting 'value')

I need to find a way to get my data from my redux store into a map function but i end up with the error below

My console gives me for

setVariants(editProduct?.variants?.map((variant) => variant));

this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

[
0:{label: 'Small', price: '5', value: 0}
1: {label: 'Medium', price: '7.5', value: 1}
2: {label: 'Large', price: '10', value: 2}
]

But this code ends to be undefined

  const [variants, setVariants] = useState([
    { label: '', price: '', value: '' },
  ]);

  useEffect(() => {
    setVariants(editProduct?.variants?.map((variant) => variant));
  }, []);

  console.log(variants);

Thats why the code below ends to be:
Uncaught TypeError: Cannot set properties of undefined (setting ‘value’)

 {variants.map((variant, index) => (
                      <div key={index} className=' mb-4'>
                        <div className='hidden'>{(variant.value = index)}</div>
                        <div>
                          <label className='block font-bold uppercase mb-2'>
                            <div className='flex'>
                              <div className='mr-2'>Variante {index + 1}</div>
                              <div className='flex justify-center items-center'>
                                <svg
                                  onClick={() => handleAddVariants()}
                                  xmlns='http://www.w3.org/2000/svg'
                                  class='h-5 w-5'
                                  viewBox='0 0 20 20'
                                  fill='currentColor'
                                >
                                  <path
                                    fill-rule='evenodd'
                                    d='M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z'
                                    clip-rule='evenodd'
                                  />
                                </svg>
                                <svg
                                  onClick={() => handleRemoveVariants(index)}
                                  xmlns='http://www.w3.org/2000/svg'
                                  class='h-5 w-5'
                                  viewBox='0 0 20 20'
                                  fill='currentColor'
                                >
                                  <path
                                    fill-rule='evenodd'
                                    d='M10 18a8 8 0 100-16 8 8 0 000 16zM7 9a1 1 0 000 2h6a1 1 0 100-2H7z'
                                    clip-rule='evenodd'
                                  />
                                </svg>
                              </div>
                            </div>
                            <div className='flex'>
                              <input
                                className='mr-4 p-2 h-8 w-36 focus:outline-none bg-gray-700 border-b-2 border-yellow-500 font-semibold'
                                type='text'
                                name='label'
                                placeholder={'Name Variante ' + (index + 1)}
                                value={variant.label}
                                onChange={(event) =>
                                  handleVariantsChangeInput(index, event)
                                }
                              />

                              <input
                                className='h-8 w-16 p-2 focus:outline-none bg-gray-700 border-b-2 border-yellow-500 font-semibold'
                                type='number'
                                step='.01'
                                min='0'
                                name='price'
                                placeholder={'Preis ' + (index + 1)}
                                value={variant.price}
                                onChange={(event) =>
                                  handleVariantsChangeInput(index, event)
                                }
                              />
                              <div className='mt-1 font-semibold'>€</div>
                            </div>
                          </label>
                        </div>
                      </div>
                    ))}

Edit

const initialVariants = [{ label: '', price: '', value: '' }];

const EditProduct = () => {...}
  const [variants, setVariants] = useState(initialVariants);

  console.log(variants);
  console.log(initialVariants);

  useEffect(() => {
    setVariants(
      editProduct?.variants?.map(
        (variant, value) =>
          ({
            ...variant,
            value,
          } ?? initialVariants)
      )
    );
  }, [editProduct]); // don't forget dependencies

>Solution :

<div className='hidden'>{(variant.value = index)}</div>

I have no idea what this is supposed to be doing but if you wanted to assign a value property from the index position, you should do that when you set the state value.

You should also provide a fallback value in case your optional chaining returns undefined

const initialVariants = [{ label: "", price: "", value: "" }];
const [variants, setVariants] = useState(initialVariants);

useEffect(() => {
  setVariants(
    editProduct?.variants?.map((variant, value) => ({
      ...variant,
      value,
    })) ?? initialVariants
  );
}, [editProduct]); // don't forget dependencies

You can display the value (index) in your render without assigning

{
  variants.map((variant) => (
    <div key={variant.value} className="mb-4">
      <div className="hidden">{variant.value}</div>
      {/* ... etc ... */}
    </div>
  ));
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading