1

In my server-side settings (knex, express), I have this function:

// POST: Create new users
app.post('/add-user', (req, res) => {
    const {firstName, lastName, emailAdd, gender, dob, password} = req.body;
    console.log(req.body)
    db('useraccounts').insert({
        first_name: firstName,
        last_name: lastName,
        email_add: emailAdd,
        gender: gender,
        dob: dob,
        password: password,
    })

And in my client-side settings I have this form and this function:

return (
    <div className="form-container">
        <form id="formSend" onSubmit={onFormSubmit}>
            <input type="text"
                   name="firstName"
                   placeholder="First Name"
                   value="James"
                   id="firstName"
                   required
            />
            <input type="text"
                   name="lastName"
                   placeholder="Last Name"
                   value="James"
                   id="lastName"
                   required
            />
            <input type="email"
                   name="emailAdd"
                   placeholder="Email Address"
                   value="jim@jim.com"
                   id="emailAdd"
                   required
            />
            <select type="text"
                    name="gender"
                    list="genderDropdown"
                    id="gender"
                    required>
                <option value="Male">Male</option>
                <option value="Female">Female</option>
            </select>
            <input type="date"
                   name="dob"
                   placeholder="D.O.B"
                   id="dob"
                   required
            />
            <input type="password"
                   name="password"
                   placeholder="Password"
                   id="password"
                   required
            />
            <input type="password"
                   name="confirmPassword"
                   id="confPass"
                   placeholder="Confirm Password"
                   required
            />
            <input type="submit" value="COMPLETE REGISTRATION" disabled={isDisabled} />
        </form>
    </div>
);

const onFormSubmit = (e) => {
    e.preventDefault();
    let formData = new FormData(e.target)
    if (verifyPassword()) {
        setIsDisabled(false)
        fetch("http://localhost:5000/add-user", {
            method: "POST",
            body: formData
        }).then((response) => {
            console.log(response);
            return response.json();
        })
    }
}

The functionality is simple:

1 - The form is filled in and populates the db.insert variables.

However, I keep on getting null value error:

error: insert into "useraccounts" ("dob", "email_add", "first_name", "gender", "last_name", "password") values (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT) - null value in column "first_name" violates not-null constraint

when I submit the form. For some reason the form data is not being passed to the variables in the other file, even though the form data is present when I output something like console.log(formData.get('firstName')

When I run the POST request in the form itself e.g. <Form method='POST' action='URL'>

The form uploads to the server no problem...anyone have any idea?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
  • May you share the HTML form too? – evolutionxbox Jul 24 '21 at 15:03
  • Please add a `catch` onto the `fetch` call and let us know what (if any) error there is. – evolutionxbox Jul 24 '21 at 15:07
  • `let formData = new FormData(e.target)` creates a new formData that gets POST'ed. This means all the data in the form is set to null. Instead, you want to be grabbing the form used above i.e. `
    ` by using something like `document.querySelector`
    – purple Jul 24 '21 at 15:39
  • this worked @purple but only in printing the formData to console. It gives the same output as insomnia too: but still gives a null column error in postgres – ComicBookGuy Jul 24 '21 at 15:45
  • Hi @bfris I understand that - the question is how I get the variables to populate so they're no longer null – ComicBookGuy Jul 24 '21 at 16:09

2 Answers2

1

Explain

For this kind of problem, the key is to know the Content-Type of the request.

When I run the POST request in the form itself e.g. The form uploads to the server with no problem.

The default Content-Type of Form element is application/x-www-form-urlencoded(see this). On the server-side, you have something like app.use(express.urlencoded({extended:true}) to parse requests in application/x-www-form-urlencoded format and it worked.

Now, you're using another Content-Type with this code let formData = new FormData(e.target). It is multipart/form-data, see the documentation. On the server-side, your req.body is empty because you don't have the right middleware to parse requests in multipart/form-data format.

(You can think of it like 2 people use 2 different languages, they can't understand each other)

Action

At least 2 choices:

  • Because Express doesn't have built-in middleware to parse multipart/form-data format, you will need to install something like multer to do the job.
  • (recommended) multipart/form-data is usually used to handle upload file requests, which isn't the case here. You can send requests in application/x-www-form-urlencoded format. You need to convert FormData to urlencoded format and set the right Content-Type header.
...
 const urlEncoded = new URLSearchParams(formData).toString();
 fetch("http://localhost:5000/add-user", {
            method: "POST",
            body: urlEncoded,
            headers: {
               'Content-Type': 'application/x-www-form-urlencoded'
            }
        }).then((response) => {
            console.log(response);
            return response.json();
        })
Đăng Khoa Đinh
  • 5,038
  • 3
  • 15
  • 33
-1

This bit of jQuery solved the issue for me:

$('#formSend').serialize(),

In the fetch API like so:

fetch("/yourHTTPpath", {
                method: "POST",
                body: $('#formSend').serialize(),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            }).then((response) => {
                console.log(response);
                return response.json();
            })