Saucy Tango Food Order Form: onSubmit not triggering

https://www.codecademy.com/journeys/front-end-engineer/paths/fecj-22-front-end-development/tracks/fecj-22-react-part-ii/modules/wdcp-22-intermediate-react-9415753c-da29-4659-8b09-b7ce9abdfe6a/projects/saucy-tango-food-order-form

So I have the form functioning how I expect it. All the fields are getting updated, but when I click submit it doesn’t trigger the onSubmit function and instead I just get the default behaviour of a page refresh. Where am I going wrong here?

import React, { useState } from "react";

function FoodOrderForm() {
  
  const [formInputs, setFormInputs] = useState({});
  
  const handleChange = ({target}) {
    setFormInputs((prev) => {...prev, target.id: target.value});
  };

  const handleSubmit = (event) => {
    alert(`Order Successful!\n Your order was ${formInputs.order}.\n Please show your confirmation number for pickup.`);
    event.preventDefault();
  }

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">Name:
        <input id="name" value={formInputs.name} onChange={handleChange} />
      </label>
      <br />
      <label htmlFor="phone">Phone: 
        <input id="phone" value={formInputs.phone} onChange={handleChange} />
      </label>
      <br />
      <label htmlFor="address">Address: 
        <input id="address" value={formInputs.address} onChange={handleChange} />
      </label>
      <br />
      <label htmlFor="order">Order: 
        <input id="order" value={formInputs.order} onChange={handleChange} />
      </label>
      <br />
      <input type="submit" value = "Submit Order" />
    </form>
  );
};

export default FoodOrderForm;

Instead of an <input> element with a type of submit, use a <button> element with a type of submit.

Unfortunately that’s not the issue. Using is a valid method but even replacing that with produces the same issue.

import React, { useState } from "react";

function FoodOrderForm() {
  
  const [formInputs, setFormInputs] = useState({});
  
  const handleChange = ({target}) {
    setFormInputs((prev) => {...prev, target.id: target.value});
  };

  const handleSubmit = (event) => {
    alert(`Order Successful!\n Your order was ${formInputs.order}.\n Please show your confirmation number for pickup.`);
    event.preventDefault();
  }

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">Name:
        <input id="name" value={formInputs.name} onChange={handleChange} />
      </label>
      <br />
      <label htmlFor="phone">Phone: 
        <input id="phone" type="tel" value={formInputs.phone} onChange={handleChange} />
      </label>
      <br />
      <label htmlFor="address">Address: 
        <input id="address" value={formInputs.address} onChange={handleChange} />
      </label>
      <br />
      <label htmlFor="order">Order: 
        <input id="order" value={formInputs.order} onChange={handleChange} />
      </label>
      <br />
      <button type="submit"> Submit Order </button>
    </form>
  );
};

export default FoodOrderForm;

The above, with button subbed in, also doesn’t trigger the onSubmit function.

Wish I could debug further but the challenge isn’t loading properly for me.

It shouldn’t be an issue, but try moving event.preventDefault() above the alert?

Also, while it’s not causing your bug, the labels shouldn’t be wrapping the inputs. The entire label should be on the line above each input.

1 Like
// You wrote:
const handleChange = ({target}) {
    setFormInputs((prev) => {...prev, target.id: target.value});
  };

This seems problematic on a number of issues.

  • First Issue. If you are using the function keyword, then the correct syntax would be:
function handleChange({target}) { ...

If you want to use an arrow function, then the correct syntax should be:

const handleChange = ({target}) => ...

You are missing the arrow.

  • Second Issue.
// This won't work
{...prev, target.id: target.value}

Instead, you can use computed property names,

{...prev, [target.id]: target.value}
  • Third Issue. The third issue has to do with how you are returning in
setFormInputs((prev) => {...prev, [target.id]: target.value});

Since you have used curly braces immediately after the arrow =>, so the curly braces will be interpreted as designating the body of the arrow function.
You can fix it in two ways:

// EITHER do an Explicit Return
setFormInputs((prev) => { 
    return {...prev, [target.id]: target.value} 
});

// OR do an Implicit Return (but wrap the object in parentheses)
setFormInputs((prev) => ( {...prev, [target.id]: target.value} ) );
// Now there is no ambiguity that the curly braces aren't meant
// to denote the body of the arrow function.

With the above in mind, consider the following version:

const handleChange = ({target}) => {
    setFormInputs((prev) => ( {...prev, [target.id]: target.value} ) );
  };
2 Likes

Wow, this is really thorough! Thanks for the tips, I’ll try them out and let you know how I get on!

2 Likes

Wonderful, it all came down to fixing the handleChange as you mentioned. Guess I need to go back and practice my function syntax!

1 Like