angular: Form data is empty when calling with ContentType header

I’m submitting a … (check one with “x”)

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see

Current behavior

var fd = new FormData();
fd.append('field', 'value');

// fires an empty request (in Chrome Developer Tools)'', fd,
{headers: new Headers({'Content-Type': 'application/x-www-form-urlencoded'}))
 .subscribe(() => console.log("request done with success"));

The request data is empty (as seen in Chrome Developer Tools).

Expected behavior

The request should not be empty (and have the same body as if the Content-Type wasn’t changed).

Minimal reproduction of the problem with instructions

Plunker with two requests, one valid (Content-Type wasn’t changed), one failing (Content-Type was changed)

Please tell us about your environment:

  • Angular version: 2.0.0
  • Browser: Chrome Latest
  • Language: TypeScript

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 27 (7 by maintainers)

Commits related to this issue

Most upvoted comments

I don’t know if it helps anyone, but after spending quite some time I found out that when using FormData we don’t have to set the content type to ‘multipart/form-data’.

Removing the code which was setting the content type to ‘multipart/form-data’ worked for me.

Would like someone to shed some light into it.

I had the same issue using fetch one time, I managed to workaround using the following function :

getFormUrlEncoded(toConvert) {
		const formBody = [];
		for (const property in toConvert) {
			const encodedKey = encodeURIComponent(property);
			const encodedValue = encodeURIComponent(toConvert[property]);
			formBody.push(encodedKey + '=' + encodedValue);
		return formBody.join('&');

And calling it this way :

const field = {field: 'value'};
     // failed request'', this.getFormUrlEncoded(field),
    {headers: new Headers({'Content-Type': 'application/x-www-form-urlencoded'}))
     .subscribe(() => console.log("request done with success"));

I’m not sure this is a durable solution, but it might help you in short time periods :

This issue has not been fixed yet as of latest version

even multipart/form-data has also similar issue. not able to add the file content to the FormData.

let formData: FormData = new FormData(); formData.append(‘file’, file,; formData.append(‘entityNumber’,this.node.number); formData.append(‘itemType’,getFileExtensionByDomainAndTab(this.node.baseModel.domainId,this.node.baseModel.dtoType));

let headers = new Headers();
headers.append('Content-Type', 'multipart/form-data;boundary='+Math.random());
headers.append('Accept', 'application/json');`/file/fileupload`, formData, headers)
  .map(res => res.json())
  .catch(error => Observable.throw(error))
    data => {
    error => {
      alert("failed to upload");

Angular: About to use multipart/form-data

Me: Please use multipart/form-data

Angular: How dare you 🖕

Thank You @PratikTheGameDever ,

Removing ( ‘Content-Type’, ‘multipart/form-data’ ) Solved my issue with httpClient

😠 I spent almost 4 hours at debuging this annoying issue… Newest version of Angular has this problem too. If I remove my headers it works, but… API requires these all.

@PratikTheGameDever God bless ur soul, I have been on this issue whole damn day… thank you

@ritikrishu thanks. Your solution works very well. But my issue laid my side laid. I appended Content-Type header but it was incorrect way to make multipart request.

Here is a working solution with Reactive forms, but a similar setup will work with template driven forms as well. template:

<form [formGroup]="form" ngSubmit="postForm()">
    <input type="file" formControlName="file" (change)="onFileChange($event)">
    <button type="submit">Upload</button>


import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http';
import { FormBuilder, Validators } from '@angular/forms';
import { Component } from '@angular/core';

    selector: 'my-selector',
    templateUrl: 'my-selector.component.html',
    styleUrls: ['my-selector.component.scss']

export class MyComponent {
        private http: HttpClient,
        private fb: FormBuilder
    ) { }


    form ={
        file: [null, Validators.required]

    postForm() {
        const formData = new FormData();
        formData.append('excel', this.file);

        const params = new HttpParams();

        const options = {
            reportProgress: true,

        const req = new HttpRequest('POST', '', formData, options);

     onFileChange(event) {
        if ( && {
            const [file] =;
            this.file = file

After consideration, I’m considering this a feature request, not a bug.

FormData is exclusively designed for encoding multipart/form-data. It’s not compatible with application/x-www-form-urlencoded - URLSearchParams is a better (supported) body type for that encoding.

It would be a new feature to support conversion of FormData to URL-encoded format. Not all FormData instances can be converted, either - file uploads for example cannot be URL-encoded.

For that reason, I don’t think this would be a good feature to implement. If you have a FormData instance you want to URL-encode, perform that encoding before passing it to Http.

In the future, a user-defined interceptor could convert FormData to a URL-encoded form automatically.