Edgar
Edgar

Reputation: 39

Get user input if no value found in mapped object

How to get userinput if no value found in mapped object. I want to make a post call with name and address. If address is null, user need to provide, if found, display address once name is selected (like cascading). Tried few different logic, but seems like I am making it more complicated than it should be.

const[address, setAddress] = useState('')
const[name, setName] = useState('')

const options = [
{
Name: "Tom",
Address: "NewYork",
},
{
Name: "Hary",
Address: null,
},
{
Name: "Hank",
Address: "florida",
}
];


const handleChnage = (e) => {
  let foundObject = options.find((option)=>option.Name === e.target.value)
  setName(e.target.value)
  setAddress(foundObject.Address)
};
const handleform = usecallback((event)=>{
  event.preventDefault();
  let data = {
    name,
    address
  }
  console.log(data)
 }

<div id="App">
    <form onSubmit={handleform}>
      <select value={name} onChange={handleChnage}>
        {options.map((option) => (
          <option value={option.Name}>{option.Name}</option>
        ))}
      </select>
      <input value={Address}/>
    </form>
  </div>

Upvotes: 0

Views: 69

Answers (1)

John Li
John Li

Reputation: 7447

Assuming that the input could get value from either select or from user input, perhaps consider to handle it with useRef instead of binding its value to a state.

This way, the user could use the recommended address from data, or they could enter a custom address. Some additional checking can be added to onSubmit to ensure values of select and input are not empty.

This example runs in the snippet for convenience:

const { useState, useRef } = React;

const options = [
  {
    Name: "Tom",
    Address: "NewYork",
  },
  {
    Name: "Hary",
    Address: null,
  },
  {
    Name: "Hank",
    Address: "florida",
  },
];

const App = () => {
  const [name, setName] = useState("");
  const inputRef = useRef(null);
  // Only for testing
  const [log, setLog] = useState([]);

  const handleChnage = (e) => {
    if (!e.target.value) {
      setName("");
      inputRef.current.value = "";
      return;
    }
    const foundObject = options.find(
      (option) => option.Name === e.target.value
    );
    setName(e.target.value);
    inputRef.current.value = foundObject.Address || "";
  };

  const handleform = (event) => {
    event.preventDefault();
    // Only for testing
    setLog((prev) => [
      `${
        !name
          ? "Please choose an option"
          : !inputRef.current.value
          ? "Please enter address"
          : `Logged: name: ${name}, address: ${inputRef.current.value}`
      }`,
      ...prev,
    ]);
  };

  return (
    <div className="App">
      <form onSubmit={handleform}>
        <select value={name} onChange={handleChnage}>
          <option value="">Please choose an option</option>
          {options.map((option) => (
            <option value={option.Name}>{option.Name}</option>
          ))}
        </select>
        <input
          ref={inputRef}
          placeholder="Please enter address"
          disabled={!name}
        />
        <button type="submit">SUBMIT</button>
      </form>
      <section>
        {log.map((item, index) => (
          <p key={index}>{item}</p>
        ))}
      </section>
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root")).render(
  <App />
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

Upvotes: 1

Related Questions