Skip to main content

How to Convert an Object to FormData in JavaScript

When you need to send data from a JavaScript object to a server, especially if it includes files, you often need to convert it into a FormData object. FormData is the standard browser API for constructing a set of key/value pairs that can be sent in an HTTP request, typically with the multipart/form-data content type.

This guide will teach you the modern and most effective methods for converting a JavaScript object into a FormData object. We will cover a simple conversion for flat objects and a more powerful, recursive solution for handling nested objects and arrays.

The Core Method: Object.entries() and forEach()

The most straightforward way to convert an object to FormData is to iterate over its key-value pairs and append each one to a new FormData instance. The Object.entries() method is perfect for this, as it returns an array of an object's [key, value] pairs.

The Solution for Simple, Flat Objects

If your object is flat (i.e., it does not contain other objects or arrays), this simple approach is all you need.

For example, how to convert this user object to FormData?

// Problem: How to convert this object to FormData?
const user = {
name: 'Alice',
email: 'alice@example.com',
id: 123,
};

Solution:

function objectToFormData(obj) {
const formData = new FormData();

Object.entries(obj).forEach(([key, value]) => {
formData.append(key, value);
});

return formData;
}

const user = { name: 'Alice', email: 'alice@example.com', id: 123 };
const formData = objectToFormData(user);

// You can verify the contents with .get()
console.log(formData.get('name')); // Output: "Alice"
note

This is a clean and effective solution for simple data structures.

Real-world objects are often nested. A simple loop will not correctly serialize nested objects or arrays for a format like multipart/form-data. For this, you need a recursive function.

const userProfile = {
id: 123,
name: 'Alice',
roles: ['admin', 'editor'], // An array
address: { // A nested object
street: '123 Main St',
city: 'Anytown',
},
};

This is the recommended best practice for a robust conversion. This function handles nested objects (using dot notation, e.g., address.city) and arrays correctly.

function buildFormData(formData, data, parentKey) {
if (data && typeof data === 'object' && !(data instanceof Date) && !(data instanceof File)) {
Object.keys(data).forEach(key => {
buildFormData(formData, data[key], parentKey ? `${parentKey}[${key}]` : key);
});
} else {
const value = data == null ? '' : data;
formData.append(parentKey, value);
}
}

function objectToFormData(data) {
const formData = new FormData();
buildFormData(formData, data);
return formData;
}

// Example Usage:
const userProfile = {
name: 'Alice',
roles: ['admin', 'editor'],
address: { city: 'Anytown' },
};

const formData = objectToFormData(userProfile);

// Check the contents
for (let [key, value] of formData.entries()) {
console.log(`${key}: ${value}`);
}

Output:

name: Alice
roles[0]: admin
roles[1]: editor
address[city]: Anytown

How this Recursive Function works:

  • buildFormData(formData, data, parentKey): This is our recursive helper. It takes the formData instance, the current piece of data to process, and the parentKey to build up nested keys.
  • Object Handling: If the data is an object (but not a File or Date), it iterates over its keys and calls buildFormData again for each nested property, constructing the key (e.g., address[city]).
  • Array Handling: The same logic handles arrays, constructing keys like roles[0], roles[1].
  • Base Case: If the data is a primitive value (string, number, boolean, null, File, etc.), it appends the parentKey and value directly to the formData.

Practical Example: Submitting a Form with fetch

The primary use case for FormData is sending data to a server. Here is how you would use our function with the fetch API.

const userProfile = {
name: 'Alice',
email: 'alice@example.com',
// Imagine an <input type="file"> element with id="avatar-input"
avatar: document.getElementById('avatar-input').files[0],
};

const formData = objectToFormData(userProfile); // Use the recursive function

fetch('https://api.example.com/users', {
method: 'POST',
body: formData, // The fetch API will automatically set the correct Content-Type header
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});

Conclusion

Converting a JavaScript object to FormData is an essential task for submitting complex data to a server.

  • For simple, flat objects, a straightforward loop over Object.entries() is sufficient.
  • For nested objects and arrays, the recommended best practice is to use a recursive function that can correctly serialize the nested structure into the key-value format that FormData expects.

By using a robust recursive helper, you can create a reliable objectToFormData utility that will work for any data structure.