How do you POST a FormData object in Angular 2?

96,788

Solution 1

It's an Open Isuue on Angular2 Git Repository, and there is also a Pull Request waiting to be merged, hope that it will be merged soon.


Alternatively,

You can use XMLHttpRequest Object directly, for that.

And don't forget to set the header

xhr.setRequestHeader("enctype", "multipart/form-data");

// IE workaround for Cache issues
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Cache-Control", "no-store");
xhr.setRequestHeader("Pragma", "no-cache");

on the XMLHttpRequest that you make.


Similar Questions:

How to upload file in Angular2

Angular 2 File upload from input type=file

Angular2 post uploaded file

Solution 2

Template:

<label class="btn btn-primary">
  <input type="file" style="display: none;" multiple="true" (change)="fileChange($event)" accept=".xml">
  <span>Click Me!</span>
</label>

UPD: Angular 5 - HttpClient + Typescript

onFileUpload(event: EventTarget) {

  const eventObj: MSInputMethodContext = <MSInputMethodContext>event;
  const target: HTMLInputElement = <HTMLInputElement>eventObj.target;
  const files: FileList = target.files;

  const formData: FormData = new FormData();

  for (let i = 0; i < files.length; i++) {
    formData.append('file', files[i]);
  }

  // POST
  this.httpClient.post<AnalyzedData>(uploadUrl, formData).subscribe(...);
}

old Http lib - before Angular 4.3:

fileChange(event) {
    let files = event.target.files;
        if (files.length > 0) {
        let formData: FormData = new FormData();
        for (let file of files) {
             formData.append('files', file, file.name);
        }
        let headers = new Headers();
        headers.set('Accept', 'application/json');
        let options = new RequestOptions({ headers: headers });
        this.http.post(uploadURL, formData, options)
            .map(res => res.json())
            .catch(error => Observable.throw(error))
            .subscribe(
            data => {
                // Consume Files
                // ..
                console.log('uploaded and processed files');
            },
            error => console.log(error),
            () => {
                this.sleep(1000).then(() =>
                    // .. Post Upload Delayed Action
                )
            });
    }
}

Solution 3

I know this has been marked answered and is pretty old, however I had an issue posting the FormData object to an OpenIdConnect AuthServer, and the file upload examples above weren't what I was looking for.

Here is my service that gets an OpenIdAuthToken:

import { Injectable } from '@angular/core';
import { Http, RequestOptions, Headers, URLSearchParams} from '@angular/http'
import { OpenIdTokenRequest, SmartData } from '../model/openid-token-request';
import { OpenIdToken } from '../model/openid-token';
import 'rxjs/add/operator/map';
import 'rxjs/Rx';
import { Observable } from 'rxjs';

@Injectable()

export class TokenService {

    constructor(private _http: Http) { }

    getToken(requestData: OpenIdTokenRequest, smartData: SmartData) {
        let _urlParams = new URLSearchParams();
        _urlParams.append('code', requestData.code);
        _urlParams.append('grant_type', requestData.grantType);
        _urlParams.append('redirect_uri', requestData.redirectUri);
        _urlParams.append('client_id', requestData.clientId);

        let _url = smartData.tokenUri;
        let _options = this.getTokenPostOptions();

        return this._http.post(_url, _urlParams, _options)
            .map(response => <OpenIdToken>response.json())
    }

    private getTokenPostOptions(): RequestOptions {

        let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' });
        let options = new RequestOptions({ headers: headers });

        return options;
    }

}

Solution 4

I solved this problem, don't need content-type at all.

See here, https://stackoverflow.com/a/45879409/2803344

Also see here to check how to set headers, Angular2 - set headers for every request

2017.8.25

Share:
96,788
Sebastian Olsen
Author by

Sebastian Olsen

Oh, hi.

Updated on July 09, 2022

Comments

  • Sebastian Olsen
    Sebastian Olsen almost 2 years

    I need to upload a file and send some json along with it, I have this function:

    POST_formData(url, data) {
            var headers = new Headers(), authtoken = localStorage.getItem('authtoken');
    
            if (authtoken) {
                headers.append("Authorization", 'Token ' + authtoken)
            }
    
            headers.append("Accept", 'application/json');
            headers.delete("Content-Type");
    
            var requestoptions = new RequestOptions({
                method: RequestMethod.Post,
                url: this.apiURL + url,
                headers: headers,
                body: data
            })
    
            return this.http.request(new Request(requestoptions))
    
            .map((res: Response) => {
                if (res) {
                    return { status: res.status, json: res.json() }
                }
            })
        }
    

    My issue is, if I set the content-type to "multipart/form-data" my server complains about the boundaries, if I remove the content-type header completely, my server complains that it "text/plain" a supported media type.

    So, how do you send FormData with angular2?

  • acastano
    acastano over 7 years
    No longer needed to use XMLHttpRequest. It works with http
  • surya
    surya over 7 years
  • fxlemire
    fxlemire over 7 years
    Many thanks for the link @surya, it worked like a charm!
  • Motassem Kassab
    Motassem Kassab over 7 years
    you also might wanna check this answer: stackoverflow.com/questions/36352405/…
  • Sreekumar P
    Sreekumar P almost 7 years
    its not an open issue now, available in latest angular
  • Jsandesu
    Jsandesu over 6 years
    For me, the important line missing was: headers.set('Accept', 'application/json');
  • Lazar Ljubenović
    Lazar Ljubenović over 6 years
    Note that this is for and old version of Http which is now (5.x) deprecated. You should use HttpClient from @angular/common/http.
  • Renato Francia
    Renato Francia about 6 years
    Using angular 5.2.3 and "UPD: Angular 5 - HttpClient + Typescript" solution worked for me for upload *.mp3 files. On the backend, I used Multer on NodeJS