Home > other >  Returning 0 when transforming string information inside a useState into parseFloat
Returning 0 when transforming string information inside a useState into parseFloat

Time:09-01

import * as C from './styles';


import AddButton from '../../components/AddButton';

import { useEffect, useState } from 'react';
import { useApi } from '../../hooks/useApi';


const AddProduct = () => {
    const api = useApi();

    const [apiCategories, setApiCategories] = useState<any[]>([]);

    const [isCreate, setIsCreate] = useState<boolean>(false);

    const [name, setName] = useState<string>('');
    const [price, setPrice] = useState<number>(0);
    const [desc, setDesc] = useState<string>('');
    const [stock, setStock] = useState<number>(0);
    const [categories, setCategories] = useState<string>('');

    const [priceSTR, setPriceSTR] = useState<string>('');
    const [stockSTR, setStockSTR] = useState<string>('');

    const [loading, setLoading] = useState<boolean>(false);
    const [error, setError] = useState<boolean>(false);

    useEffect(() => {
        const category = async () => {
          const categories = await api.getCategories();
          setApiCategories(categories);
        }
        category();
      }, []);  
    
    const onSubmit = async () => {
        try {
            setLoading(true);
            const priceFLT = parseFloat(priceSTR);
            const stockINT = parseInt(stockSTR);
            setPrice(priceFLT);
            setStock(stockINT);
            setLoading(false);
            await api.postProduct(name, price, desc, stock, categories);
            setIsCreate(true);
            setError(false);
            setName('');
            setDesc('');
            setPriceSTR('');
            setStockSTR('');    
        } catch (err) {
            setError(true);
            console.log(err);
        }
    }

  return (
    <C.Container>
        <C.Post>
            <C.Input 
                placeholder='Product name'
                value={name}
                onChange={e => setName(e.target.value)}
            />
        </C.Post> 
        <C.Post>
            <C.Desc 
                placeholder='Simple desc...'
                value={desc}
                onChange={e => setDesc(e.target.value)}
            />
        </C.Post>
        <C.Post>
            <C.Input 
                placeholder='Price'
                value={priceSTR}
                onChange={e => setPriceSTR(e.target.value)}
            />
        </C.Post>
        <C.Post>
            <C.Input 
                placeholder='Stock'
                value={stockSTR}
                onChange={e => setStockSTR(e.target.value)}
            />
        </C.Post>
        <C.Post>
            <C.Categories 
                onChange={(e) => setCategories(e.target.value)}
            >
                <option value="Todas categorias">Choose a category</option>
                {apiCategories.map(category => {
                return (
                    <option value={`${category.name}`}>{category.name}</option>
                )
                })}
            </C.Categories>
        </C.Post>
        <C.Add>
            <AddButton 
                children='Send'
                type='submit'
                onClick={onSubmit}
            />
        </C.Add>
        {isCreate ? (
            <p id='check'>Product Created!</p>
        ) : null} 
        {error ? (
            <p id='error'>Error!</p>
        ) : null} 
    </C.Container>
  )
}

export default AddProduct

My real purpose is to get the information from these inputs and send it to the "useApi" hook to validate the registration of a new product. However, the "price" and "stock" states in the API must be sent as float and int respectively, but I would like to get the information in string to then transform to float and int, and then send it to the API. It's what I try to do with

const priceFLT = parseFloat(priceSTR);
const stockINT = parseInt(stockSTR);
setPrice(priceFLT);
setStock(stockINT);

I can ship, but the stock and price always ends up as "0". How can I solve this problem?

ps: I would like to get this information in string in the input to be able to use placeholder and to be able to use "." to set a price.

CodePudding user response:

You don't actually need to update a state for price or stock to provide it to your api call

        ...
        const priceFLT = parseFloat(priceSTR);
        const stockINT = parseInt(stockSTR);
        setLoading(false);
        await api.postProduct(name, priceFLT, desc, stockINT, categories);
        ...

setPrice or setStock are asynchronous, so the update is not immediate, that is partially why you end up with 0 (the default value) when you try to immediately use price or stock variables (another more complex reason is due to the way useState and reference work, once updated the price variable inside the onSubmit that has been called is not the same as the price variable that has been updated)

  • Related