Search code examples
angularapimultipartform-dataform-data

Angular how to progamatically send a Form Data


There seems to be no good docs online about sending an api request with a form data.

As soon as you google it google automatically assumes you want to create a client-side reactive forms gui, the actual API part be damned.

and even when you follow their guides to the end you don't get a Form Data section in your browser console.

this is what I want :

a Form Data entry to be present in browser console

however my call looks like this :

call without form data section

here is my current code (component.ts) :

  public picture: FormData;

  addedImage(event) {
    this.picture = event.addedFiles[0];
    console.log(this.picture);
    this.api.uploadFile(this.picture).subscribe();
  }

...and the api part (apis.ts) :

 public uploadFile(file){
    const url = AppGlobal.API_URL + 'provisioning/api/files';
    let httpParams = new HttpHeaders();
    httpParams = httpParams.set('Content-Type', 'multipart/form-data');
    console.log(httpParams);
    return this.http.post<any>(url, file, {headers: httpParams}).pipe(
      map((data: any) => {
        console.log('return ', data);
          if(data) this.s.latestFileId$.next(data);
        }
      ));
  }

here is what is outputted by the console.log in component.ts above :

File {name: "image.jpg", lastModified: 1568824078958, lastModifiedDate: Wed Sep 18 2019 18:27:58 GMT+0200 (Central European Summer Time), webkitRelativePath: "", size: 69192, …}
lastModified: 1568824078958
lastModifiedDate: Wed Sep 18 2019 18:27:58 GMT+0200 (Central European Summer Time) {}
name: "image.jpg"
size: 69192
type: "image/jpeg"
webkitRelativePath: ""
__proto__: File
api.calls.ts:41 

...and by the console.log in apis.ts

HttpHeaders {normalizedNames: Map(0), lazyUpdate: Array(1), headers: Map(0), lazyInit: HttpHeaders}
headers: Map(0)
size: (...)
__proto__: Map
[[Entries]]: Array(0)
length: 0
lazyInit: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}
lazyUpdate: [{…}]
normalizedNames: Map(0) {}
__proto__: Object

what am I doing wrong?

here is another faulty syntax that I tried (component.ts) :

  addedImage(event) {
    var oOutput = document.querySelector("div"), oData = new FormData();
    oData.append("myfile", event.addedFiles[0], "filename.txt");
    this.picture = event.addedFiles[0];
    console.log(this.picture);
    this.api.uploadFile(oOutput);
  }

(apis.ts) :

  public uploadFile(file){
    const url = AppGlobal.API_URL + 'provisioning/api/files';
    const oReq = new XMLHttpRequest();
    oReq.open('POST', url, true);
    oReq.onload = function(oEvent) {
      if (oReq.status == 200) {
        console.log('upload success');
      } else {
        console.log('upload fail');
      }
    };

    oReq.send(file);
  }

Solution

  • Use FormData API

    const formData: FormData = new FormData();
    formData.append('files[]', event.addedFiles[0]);
    let httpParams = new HttpHeaders();
    httpParams = httpParams.set('Accept', '*/*');
    this.http.post('some/url', formData, {headers: httpParams})
    

    You can also refer this guide. This is not Angular specific though.