Search code examples
reactjsjsondrop-down-menuonchange

The Select Dropdown doesn't update back after reload


I created a form where the user inputs data and when the button Save is clicked the data are saved to a database. Everything works fine. You can notice that the country is selected from a memo list and I used a function to save the data rather than a lambda function like the name and the address because I couldn't figure it out. My problem is when I reload the page the country doesn't get back to the form like the name and the address but is stored in the database. The issue is in the code below.

import React, {useState, useEffect , useMemo} from 'react';
import { Button, Row, Col, Form, InputGroup} from 'react-bootstrap';
import obtainFromServer from '../Services/fetchService';
import { useLocalState } from '../util/useLocalStorage';
import countryList from 'react-select-country-list';
import Select from 'react-select';

const TrademarkView = () => {
    const [jwt, setJwt] = useLocalState("", "jwt"); //Remove setJwt if we don't use it at the end
    const trademarkId = window.location.href.split("/trademarks/")[1];
    const [trademark, setTrademark] = useState({
        address: "",
        country: "",
        name: "",
    });


    //Countries
    const [countryinit, setCountryinit] = useState({
        value: "",
        label: "",
    });
    const options = useMemo(() => countryList().getData(), []);

    const changeHandler = countryinit => {
        setCountryinit(countryinit);
        console.log(countryinit);
        updateTrademark("country",countryinit.label)        
      }
    const styleCountries = {
        display: "inline-block",
        width: "300px"
      };


    function updateTrademark(prop, value){
        const newTrademark = {...trademark}
        newTrademark[prop] = value;
        setTrademark(newTrademark);
    }

    function saveTrademark(){
        obtainFromServer(`/api/trademarks/${trademarkId}`, "PUT", jwt, trademark).then(
            (trademarkData) =>{
                setTrademark(trademarkData);
        });
    }

    useEffect(() => {
        obtainFromServer(`/api/trademarks/${trademarkId}`, "GET", jwt)
        .then(trademarkData => {
            if(trademarkData.address === null) trademarkData.address = "";
            if(trademarkData.name === null) trademarkData.name = "";
            setTrademark(trademarkData);
        });
    },[])

    return (
        <div>
            {trademark ? (
                <>

            <Row>
                <Col>
                    <Form className='m-5'>
                        <Form.Group controlId="formGridName" className="mb-2">
                            <Form.Label>Name:</Form.Label>
                            <Form.Control value={trademark.name} onChange={(e) => updateTrademark("name",e.target.value)}/>
                        </Form.Group>
                        <Form.Group className="mb-3" controlId="formGridAddress">
                            <Form.Label>Address:</Form.Label>
                            <Form.Control as="textarea" placeholder="1234 Main St" rows={3} value={trademark.address} onChange={(e) => updateTrademark("address",e.target.value)}/>
                        </Form.Group>
                        <Form.Group className="mb-3" controlId="formGridCountry">
                            <Form.Label>Country:</Form.Label>
                            <div style={styleCountries}><Select options={options} value={countryinit} onChange={changeHandler} /></div>
                        </Form.Group>
                    </Form>
                </Col>
                <Row className='mx-1 px-5'>
                    <Button onClick={() => saveTrademark()}>Save</Button>                    
                </Row>
                
            </Row>
            </>
            ) : (
                <></>
            )}
           
        </div>
    );
};

export default TrademarkView;

The countryinit has a value(it's the initials of the country) and a label(it's the name of the country). You can see that when I am updating the database I am only sending the label. I have a console.log so you can see the country object.

How can I get the country to be selected after a reload?


Solution

  • I finally figured it out. Changed the select to this and it worked.

    <Select options={options} value={options.filter((option) => option.value === trademark.country)} onChange={(e) => updateTrademark("country",e.value)} />
    

    Basically the problem as I mention before is that the country it was an object. And I couldn't send the whole object to the database and I was sending the label which it was wrong. Now I am sending the value to the database and when reading I am redirecting the value from the database to the selected value and setting the label.