Skip to content
tezvyn:

FormData: The Right Way to Upload Files

Source: developer.mozilla.orgMediumHow cards are made

FormData: The Right Way to Upload Files

FormData is your digital envelope for file uploads. It packages files and text into a multipart/form-data payload for fetch. Use it in React Native to upload images or videos. The footgun: don't set the Content-Type header yourself; fetch handles it.

Why it exists

HTTP requests are fundamentally text-based, but files are binary. Sending a file requires a special format to tell the server where the text data ends and the binary file data begins. The multipart/form-data encoding solves this, and the FormData interface is the standard JavaScript API for building that payload without messy, error-prone string manipulation.

The mental model

Imagine you're mailing a package with several items and a letter. You can't just throw them all in a box. You need to label each item and separate them with dividers. FormData is the API that acts as your packer, creating a multipart/form-data payload where each key/value pair is a separate, labeled "part" in the request body. This allows a server to easily parse mixed content like text fields and files.

How it works

You create a new FormData() object. Then, you use the .append(key, value) method to add data. The value can be a string for a text field or a special object for a file. In React Native, a file is typically represented as { uri: file.uri, type: 'image/jpeg', name: 'photo.jpg' }. When you pass this FormData object as the body of a fetch request, the runtime automatically serializes it into the correct multipart/form-data format and, crucially, sets the Content-Type header with a unique boundary identifier.

When to use it

Use FormData whenever you need to send a file (image, video, PDF, etc.) from your app to a server. It is the standard for any "file upload" feature. It's also the correct tool for submitting complex forms that mix text inputs and files in a single request.

When not to use it

For API calls that only send structured data like strings and numbers, stick with a plain JavaScript object, JSON.stringify it, and set the Content-Type header to application/json. Using FormData for simple JSON data is inefficient overkill; its purpose is to handle multipart bodies.

One canonical example

To upload a photo in React Native after getting it from an image picker:

const data = new FormData();
data.append('userId', '123');
data.append('photo', {
uri: image.uri,
name: 'profile.jpg',
type: 'image/jpeg',
});
fetch('https://api.example.com/upload', {
method: 'POST',
body: data,
});

Notice no Content-Type header is set manually. This is the correct and required approach.

Interview question

When using FormData with `fetch` for a file upload, what is the correct approach for the `Content-Type` header?

  • a.Set it to text/plain if only a single file is being uploaded.
  • b.Manually set it to multipart/form-data with a boundary string.
  • c.Omit the header, allowing `fetch` to automatically configure it.Correct
  • d.Manually set it to application/json if text fields are included.
Why?

The card explicitly states that when a FormData object is passed as the body of a fetch request, the runtime automatically sets the Content-Type header with a unique boundary identifier. Manually setting this header, especially to 'multipart/form-data' (a tempting distractor), would override this crucial automatic behavior and likely cause the upload to fail.

Just read this? Test yourself on what you have been reading.

Read the original → developer.mozilla.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on react-native — each one lists the topics its interview covers.

See open roles