Home > Software engineering >  React - Axios put request to update only specific fields
React - Axios put request to update only specific fields

Time:09-30

Relatively new to react and working on a project with a backend. Basically all functionality works accordingly, however, I am a little unsure on how to implement a put request that allows me to send only specific values to backend.

WHAT HAPPENS: when I send a request to update a company it requires me fill out all fields. If I leave fields empty, it will send them as null.

E.G:

company has fields of name, email,password. I would like to update ONLY email field without changing the others.

Component:

function UpdateCompany(props): JSX.Element {

  const history = useHistory();
  const [name , setName] = useState('');
  const [email , setEmail] = useState('');
  const [password , setPassword] = useState('');
  const [skipCount, setSkipCount] = useState(true); 

  async function formData() {
    try {

      const response = await axios.put<CompanyModel>(globals.adminUrls.updateCompany   props.location.state.id, {
        name: name,
        email: email,
        password: password
      });

      const updated = response.data;
      store.dispatch(companyUpdatedAction(updated));
      notify.success(SccMsg.COMPANY_UPDATED)

    }
    catch (err) {
      notify.error(err);
    }
  }

  const handleSubmit = (e) => {
      e.preventDefault();
      formData();
  }

  useEffect(() => {
    if (skipCount) setSkipCount(false);
    if (!skipCount)  formData();

}, []);

  return (
    <div className="custom-field">
      <h2>Update Company</h2>
      <div>
        <form onSubmit={handleSubmit} >
          <label>Name</label>
        <input type="text" name="name" onChange={(e)=>{setName(e.target.value)}}/>
        <label>Email</label>
        <input type="text" name="email" onChange={(e)=>{setEmail(e.target.value)}}/>
        <label>Password</label>
        <input type="text" name="password" onChange={(e)=>{setPassword(e.target.value)}}/>

        <input  type="submit" name="submit"/>
        </form>
      </div>

    </div>
  );
}

export default UpdateCompany;

Hope I am clear on my questions.

Thanks.

Backend Controller:

@PutMapping(value = "update/company/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    @Override
    public void updateCompany(@PathVariable int id, @RequestBody CompanyDto companyDto) throws DoesNotExistException, AlreadyExistsException {
        adminService.updateCompany(id, companyDto);

Backend Service:

 public void updateCompany(@Valid int id, CompanyDto companyDto) throws DoesNotExistException, AlreadyExistsException {

Company companyDao = companyMapper.toDao(companyDto);

if (!compRepo.existsById(id))
    throw new DoesNotExistException("Company does not exist");

companyDao.setId(id);

compRepo.saveAndFlush(companyDao);

CodePudding user response:

Just use a simple if condition to perform a null check while populating the PUT request body. You can do it in the following way:

async function formData() {
    try {
     const data = {};
     if(name) data.name = name; 
     if(email) data.email = email;
     if(password) data.password = password
     
     const response = await axios.put<CompanyModel>(globals.adminUrls.updateCompany   props.location.state.id, data);

      const updated = response.data;
      store.dispatch(companyUpdatedAction(updated));
      notify.success(SccMsg.COMPANY_UPDATED)

    }
    catch (err) {
      notify.error(err);
    }
  }

CodePudding user response:

You’ll need to get the current values, then set initial state with them.

This will have the added benefit of showing the current values within the input fields on the form. For this reason, the added call is justified, and very miniscule anyways (how often will company info really be updated??).

Something like this could work:

const [name , setName] = useState('');
const [email , setEmail] = useState('');
const [password , setPassword] = useState('');

// Get the current data, so you can set initial state with it.
useEffect(() => {
    const currentData = await axios.get<CompanyModel>();

    setName(currentData.name);
    setEmail(currentData.email);
    setPassword(currendData.password);

    if (skipCount) setSkipCount(false);
    if (!skipCount)  formData();
}, []);


async function formData() {

  .....

   const response = await axios.put<CompanyModel>(globals.adminUrls.updateCompany   
      props.location.state.id, {
       name: name,
       email: email,
       password: password
     });

   const updated = response.data;

  ......

}

With this example, you're values will simply remain the same unless the user types something else in the form.

The only thing you may need to change is the get request, as I'm not familiar with your end point.

  • Related