JavaScript FormData: Collect Form Data for APIs
Learn how to collect form values with FormData, read entries, build request data and send forms to APIs.
What you will learn
Reading every form field manually works for small forms, but it becomes repetitive when a form has many fields.
FormData gives you a simple way to collect the fields of a form into one object-like structure. In this lesson you will learn how to create FormData, read its entries, work with checkboxes and files, and convert form data into JSON when an API needs JSON.
The concept
Suppose you have this form:
<form id="profile-form">
<input name="name" type="text">
<input name="email" type="email">
<input name="age" type="number">
<button type="submit">Save</button>
</form>
You can collect the form with:
const form = document.getElementById("profile-form");
const formData = new FormData(form);
Now formData contains the successful form controls that have names.
Tip: A form control normally needs a
nameattribute to be included whenFormDatais created from a form.
Why name matters
This will be included:
<input name="email" type="email">
This will not provide a named field:
<input id="email" type="email">
The id is useful for JavaScript and labels, but FormData uses the control’s name.
Reading FormData
You can read a value with .get():
const formData = new FormData(form);
console.log(formData.get("name"));
console.log(formData.get("email"));
For example, if the user enters:
Name: Riya
Email: riya@example.com
then:
console.log(formData.get("name")); // Riya
console.log(formData.get("email")); // riya@example.com
If the field does not exist, .get() returns null.
Loop through all form data
Use entries():
for (const [key, value] of formData.entries()) {
console.log(key, value);
}
You can also use:
for (const [key, value] of formData) {
console.log(key, value);
}
This is useful for debugging or when you do not know all the fields in advance.
Convert FormData to an object
A very useful pattern is:
const data = Object.fromEntries(formData.entries());
console.log(data);
For this form:
<input name="name" value="Riya">
<input name="email" value="riya@example.com">
you get an object similar to:
{
name: "Riya",
email: "riya@example.com"
}
Converting to JSON
If an API expects JSON:
const data = Object.fromEntries(formData.entries());
const json = JSON.stringify(data);
console.log(json);
You can send it with fetch():
fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
Tip:
FormDataitself is not JSON. Convert it to an object and then useJSON.stringify()when your API expects JSON.
Sending FormData directly with fetch
If the server accepts multipart/form-data, you can send FormData directly:
const formData = new FormData(form);
fetch("/api/users", {
method: "POST",
body: formData
});
Do not manually set:
headers: {
"Content-Type": "multipart/form-data"
}
when sending FormData directly from the browser. The browser needs to add the correct boundary automatically.
FormData is useful for file uploads
Suppose your form contains:
<form id="upload-form">
<input name="username" type="text">
<input name="avatar" type="file">
<button type="submit">Upload</button>
</form>
Then:
const form = document.getElementById("upload-form");
const formData = new FormData(form);
console.log(formData.get("username"));
console.log(formData.get("avatar"));
The avatar value can be a File object.
You can send the complete form:
fetch("/api/profile", {
method: "POST",
body: formData
});
This is one of the most common real-world uses of FormData.
append() and set()
You can add data manually.
const formData = new FormData();
formData.append("name", "Riya");
formData.append("course", "JavaScript");
Read it:
console.log(formData.get("name"));
console.log(formData.get("course"));
append() can create multiple values
formData.append("skill", "HTML");
formData.append("skill", "CSS");
formData.append("skill", "JavaScript");
Now there are multiple skill entries.
console.log(formData.getAll("skill"));
Result:
["HTML", "CSS", "JavaScript"]
set() replaces the existing value
formData.set("name", "Karan");
If name already exists, set() replaces its value.
A simple difference:
| Method | What it does |
|---|---|
append() |
Adds another value |
set() |
Sets/replaces the value |
Check whether a field exists
Use .has():
if (formData.has("email")) {
console.log("Email exists");
}
Delete a field
formData.delete("age");
This can be useful when you want to remove optional data before sending a request.
Checkboxes and FormData
Consider:
<label>
<input name="newsletter" type="checkbox" value="yes">
Subscribe to newsletter
</label>
If the checkbox is checked, it can appear in FormData:
const formData = new FormData(form);
console.log(formData.get("newsletter"));
If it is not checked, there may be no newsletter entry.
That means this:
formData.get("newsletter")
can return:
null
when the checkbox was not selected.
If you want a reliable boolean for application logic, you can read the checkbox itself:
const newsletter = document.querySelector(
'input[name="newsletter"]'
).checked;
Select and textarea
FormData also works with common form controls.
<select name="country">
<option value="in">India</option>
<option value="jp">Japan</option>
</select>
<textarea name="message"></textarea>
Then:
const formData = new FormData(form);
console.log(formData.get("country"));
console.log(formData.get("message"));
A complete API example
HTML:
<form id="contact-form">
<input name="name" type="text" placeholder="Name">
<input name="email" type="email" placeholder="Email">
<textarea name="message" placeholder="Message"></textarea>
<button type="submit">Send</button>
</form>
JavaScript:
const form = document.getElementById("contact-form");
form.addEventListener("submit", async function (event) {
event.preventDefault();
const formData = new FormData(form);
const data = Object.fromEntries(formData.entries());
console.log(data);
const response = await fetch("/api/contact", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
});
if (response.ok) {
console.log("Message sent.");
} else {
console.log("Something went wrong.");
}
});
This pattern is useful when your backend expects JSON.
When should you use FormData?
Use FormData when:
- You want to collect many form controls easily.
- You are submitting a normal HTML form to JavaScript.
- You need to upload files.
- Your API accepts
multipart/form-data. - You want to avoid manually reading every field.
If your API only accepts JSON, convert the collected data into an object and then JSON.
Common mistakes
- Forgetting
nameattributes. Form controls without names are not included as named form fields. - Thinking FormData is a normal JavaScript object. It is a special browser object with methods such as
.get(),.append()and.entries(). - Trying
JSON.stringify(formData)directly. Convert it first when you need JSON. - Manually setting
Content-Type: multipart/form-data. Let the browser set the boundary when sending FormData. - Expecting unchecked checkboxes to appear. An unchecked checkbox may have no entry.
- Forgetting that values can be strings. Convert numeric strings when your application needs actual numbers.
- Sending invalid data because “FormData collected it.” Collection and validation are separate jobs. Validate before sending.
Practice
- Create a form with name, email, age and city and print all FormData entries.
- Use
.get()to print only the name and email. - Convert FormData into a plain object using
Object.fromEntries(). - Convert that object into JSON using
JSON.stringify(). - Add a checkbox and observe what happens when it is checked and unchecked.
- Challenge: Create a profile form with a name, email, skills and profile image, then send it with
fetch()as FormData. - Challenge: Create a contact form and convert its FormData to JSON before sending it to a mock API.
Recap
FormDatacollects form controls into a browser-friendly data structure.- Use
.get()to read one value. - Use
.entries()to loop through fields. - Use
.append()to add values and.set()to replace them. - Use
Object.fromEntries()when you need a plain object. - Use
JSON.stringify()when an API expects JSON. - Send FormData directly when the server accepts
multipart/form-data, especially for file uploads. - Do not manually set the multipart
Content-Typeboundary when sending FormData from the browser.