In this lesson, you'll learn how to interact with the built-in FormData object to easily grab all the data in a form and package it up into a convenient data structure.
Setting Up the Example Form
Say for example you had this form:
<form id="demo-form">
<label for="name"></label>
<input id="name" name="name" value="Nomad" />
<input id="age" name="age" type="number" value="14" />
<input id="date" name="date" type="date" value="2021-12-15" />
<input type="submit" />
</form>
You'll note that in this form you are initializing some input elements with values so that every time you refresh, you don't have to manually type them in!
Here is the JavaScript for this form to get you started:
const form = document.querySelector(`#demo-form`);
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
}
form.addEventListener(`submit`, handleSubmit);
Here is a CodePen with the form and the JavaScript set up for you: https://codepen.io/CodingNomads/pen/poGxzaZ
How to Use the FormData Object
Now that you are set up, it's time to figure out how to use FormData.
FormData is similar to Date, in the sense that you instantiate a FormData object with the new keyword. With a Date constructor, you can pass in something that represents a date, with FormData you can pass in the form element itself:
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form); // <-- pass in the form element
}
Now that you have your FormData object, you'll need to grab the values from it. Unfortunately FormData doesn't behave exactly like an object. It's a little bit different. You'll see how in the next section.
How to Iterate Through FormData
Now that you have your form data, you might expect it to behave like an object with key, value pairs. That's something you'd like to have, right?
But you can't grab the values directly:
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
console.log(formData.name); // undefined
console.log(formData['age']); // undefined
console.log(formData[0]); // undefined
}
FormData has methods that return objects that are iterable. In a previous lesson, you've covered iterator protocols in JavaScript, and why you'll have some objects that aren't indexable like arrays or objects, but are still iterable.
FormData Iterables
FormData also has a couple of methods that return iterables:
.entries()- returns an iterator that returns an array of key, value pairs.keys()- returns an iterator that returns the keys.values()- returns an iterator that returns the values
You can then use these iterators in a for...of loop:
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
for (let keyValue of formData.entries()) {
console.log(keyValue);
}
}
/* OUTPUT (on form submit)
["name", "Nomad"]
["age", "14"]
["date", "2021-12-15"]
*/
As you can see, the .entries() method returns an iterator that returns an array of key, value pairs.
If you're crafty, you might have noticed that there's a .forEach() method on FormData, but this .forEach() is slightly different from the one you're used to. It's not the one that's on the Array.prototype object. It's a different one that's on the FormData.prototype object. The first two arguments for the callback function are the value and the key, respectively:
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
formData.forEach((v, k) => console.log(v, k));
}
/* OUTPUT (on form submit)
Nomad name
14 age
2021-12-15 date
*/
Learn by Doing
Quick challenge, set up a form with various inputs of different types and then use FormData get all the information into an object and print each key, value pair to the console.
Once you have a solution, read the rest of this lesson for some solutions.
How to Collect the Data from FormData into an Object
If you wanted to create an object from the FormData object, you could do something like this:
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
const data = {};
for (let keyValue of formData.entries()) {
data[keyValue[0]] = keyValue[1];
}
console.log(data);
}
/* OUTPUT (on form submit)
{name: "Nomad", age: "14", date: "2021-12-15"}
*/
That is, instantiating and empty object, and then going through the key value pairs, populating the object in each iteration.
Alternatively, just for fun, and to be super-functional. You could use the .reduce() array method, which you'll cover in more detail in a future lesson. The .reduce() method is perfect for converting an array into an object. That said, since FormData doesn't have a .reduce() method, you'll have to convert the iterator into an array first:
function handleSubmit(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
const data = Array
.from(formData.entries())
.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {});
console.log(data);
}
/* OUTPUT (on form submit)
{name: "Nomad", age: "14", date: "2021-12-15"}
*/
This method is treading the line between being functional, or just being a show-off. As you can see, it's not as readable as the previous example, but that may be because aren't familiar with the .reduce() method yet. In any case, you'll be covering .reduce() in more detail in a future lesson.
Summary: How to Access Input Values Using the JavaScript FormData Object
In this lesson, you've:
- Discovered that a new
FormDataobject is created by passing in a form element. - Recognized that you can't access
FormDatavalues using typical object syntax like dot notation or bracket notation; instead, you use methods such as.entries(),.keys(), and.values(). - Practiced iterating through the
FormDatausingfor...ofloops and the.entries()method to log out key-value pairs from the form. - Explored the use of
FormData's.forEach()method, which is specialized for this object, with the callback arguments ordering value first, then key. - Learned two methods to convert
FormDatainto a regular object using afor...ofloop and the.reduce()array method.
Great job getting to grips with these concepts; practicing these will help you handle forms more effectively in your web applications!