Jason Byron Beedle
Jason Byron Beedle

Reputation: 73

My react-dropdown-select item is undefined

I am attempting to parse the dropdown item that is selected into a Prop. I get an error of

TypeError: Cannot read property 'name' of undefined

I have attempted to make a new Prop and parse it through there and that did not work either. I have also tried to add all array into the formData to no avail. When I do not add the dropdown menu the Format and Location are parsed no problem, as soon as they change to the dropdown's it does not get read. I think the dropdowns change them into another format and not a string. .

The addFixture.js code is below:


const AddFixture = ({ addFixture, history }) => {
  const [formData, setFormData] = useState({
    teams: '',
    opposition: '',
    date: '',
    format: '',
    location: '',
  });

  const {
    teams,
    opposition,
    date,
    format,
    location
  } = formData;

  const overs  = [
    { value: '40 Overs', label: '40 Overs' },
    { value: '20 Overs', label: '20 Overs' },
  ]

  const hOrA = [
    { value: 'Home', label: 'Home' },
    { value: 'Away', label: 'Away' },
  ]

  const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });


 
      <form
        className="form"
        onSubmit={(e) => {
          e.preventDefault();
          addFixture(formData, history);
        }}
      >

        <div className="form-group">
          <Select
            type="text"
            placeholder="* Location"
            name="location"
            value={location}
            options={hOrA}
            onChange={onChange}
            required
          />
        </div>
        <div className="form-group">
          <Select
            type="text"
            placeholder="* format"
            name="format"
            value={format}
            onChange={onChange}
            options={overs}
            required
          />
        </div>
      
      </form>

  );
};

AddFixture.propTypes = {
  addFixture: PropTypes.func.isRequired
};

Upvotes: 1

Views: 2047

Answers (1)

Moshe Sommers
Moshe Sommers

Reputation: 1516

  1. React select expects the value to match one of the dropdown values - So
    value={location} //needs to match the object {value:string, label:string}

  2. React select passes in the full value of the selected option to the onChange so

    onChange={onChange} //onChange={(val:{value:label}) => {}}
    

    You can pass in the name of the dropdown like so

    onChange={(val) => onChange(val,nameOfDropdown )}

    Then use the name passed in like so

    const onChange = (selected, name) =>{        
        setFormData({ ...formData, [name]: selected.value });
    }
    

With all these changes your code should look something like this

const AddFixture = () => {
    const [formData, setFormData] = useState({
     format: '',
     location: '',
    });

    const {
      format,
      location
    } = formData;

   const overs  = [
      { value: '40 Overs', label: '40 Overs' },
      { value: '20 Overs', label: '20 Overs' },
    ]

    const hOrA = [
      { value: 'Home', label: 'Home' },
      { value: 'Away', label: 'Away' },
    ]

   /** onChange will get passed value from the dropdown {value:string, label:string} */
    const onChange = (selected, name) =>{        
        setFormData({ ...formData, [name]: selected.value });
    }

    return(
      <>
          <div className="form-group">
            <Select
              type="text"
              placeholder="* Location"
              name="location"
              /** Need to set this to one of the dropdown values  {value:string, label:string} */
              value={hOrA.find((val) => val.value === location)}
              options={hOrA}
              onChange={(val) => onChange(val,"location" )}
              required
            />
          </div>
          <div className="form-group">
            <Select
              type="text"
              placeholder="* format"
              name="format"
              /** Need to set this to one of the dropdown values  {value:string, label:string} */
              value={hOrA.find((val) => val.value === format)}
              onChange={(val) => onChange(val,"format" )}
              options={overs}
              required
            />
          </div>
       </>
    );
};

Upvotes: 3

Related Questions