JavaScript – FormData initialized from a form element is empty

Problem

When you try to initialize a FormData object from a form element, it’s empty. There are no keys or values whatsoever.

For example, let’s say you’re trying to post form data with fetch():

const response = await fetch("https://localhost:12345/movies/", {
        method: 'POST',
        body: new FormData(movieForm)
    });
Code language: JavaScript (javascript)

When you look at the request, it has the right Content-Type, but no data:

POST https://localhost:12345/movies/
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGvI8IjdQFIdAgpUv
Code language: plaintext (plaintext)

Note: If you look in DevTools > Network, you’ll notice the Payload tab is empty.

On the server-side, you can see that no form data is coming through with the request.

Solution

Make sure your form input fields have a name attribute:

<form id="movieForm">
    <label for="title">Title</label>
    <input type="text" id="title" name="title"/>
    <button type="submit">Save</button>
</form>
Code language: HTML, XML (xml)

When you initialize FormData() from a form element, it’ll only map input fields that have a name attribute. Only these mapped input fields are included in the form data that is sent in requests. Hence, when none of the input fields are mapped, the form data will be empty.

After fixing the problem, the request will contain the form data as expected:

POST https://localhost:12345/movies/
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryJXa9euxPDcKFOcJe

------WebKitFormBoundaryJXa9euxPDcKFOcJe
Content-Disposition: form-data; name="title"

Dune
------WebKitFormBoundaryJXa9euxPDcKFOcJe
Content-Disposition: form-data; name="yearReleased"

2021
------WebKitFormBoundaryJXa9euxPDcKFOcJe
Content-Disposition: form-data; name="number"

9
------WebKitFormBoundaryJXa9euxPDcKFOcJe--
Code language: plaintext (plaintext)

What if the input field value is empty?

When the input field value is empty (such as if the user didn’t input anything and there’s no default), then FormData will map it anyway. It will map the input field as long as it has a name attribute.

Depending on how the web API is handling form data, a request with empty form values may result in an error response. Use default values and make fields required (when appropriate) to avoid this. If you really need to send empty/null values, then remove the key/value pair from the form data instead.

FormData appears empty in the console

One thing that makes troubleshooting this confusing is that FormData appears to be empty when it’s not. This is misleading, but it’s just the way FormData works.

The simplest way to look at the data is to use Array.from():

Array.from(new FormData(movieForm))
Code language: JavaScript (javascript)

This will output an array of key/value pairs.

Comments are closed.