YYY
YYY

Reputation: 3520

Angular 6 file upload with form content

I have create a page with different input elements with file upload. While saving the form with multiple files along with form input elements using angular 6, the file object is empty {} in console an http service in network tab.

Here is my code:

onFileChanged(event) {    
    this.selectedFiles = event.target.files; 
    const uploadData = new FormData();
    uploadData.append('myFile', this.selectedFiles, this.selectedFiles[0].name);    
    this.createFormData.attachment = uploadData;   
};

Can anyone provide a sample to help me?

Upvotes: 1

Views: 5577

Answers (2)

iLuvLogix
iLuvLogix

Reputation: 6420

Have a look at following example with npm's ng2-file-upload (in this case with a fontAwsome-icon).

myFileUploadForm.component.html:

                  <!-- file upload -->
                  <input #fileToUpload type="file" style="display:none;" ng2FileSelect (change)="onFileChanged($event)" [uploader]="uploader"
                    name="customerFile" id="customerFile" class="customerFile" />
                  <a href="javascript:document.getElementById('customerFile').click();">
                    <fa class="ql-upload" *ngIf="buttonDeaktivieren" [title]="'Upload'" [name]="'upload'" [size]="0.9" [border]=false></fa>
                  </a>

myFileUploadForm.component.ts (I'll ommit the obvious parts with ..):

import { Component, OnInit, ViewChild, OnDestroy, TemplateRef } from '@angular/core';
import { Subscription, Observable } from '../../../../../node_modules/rxjs';
....
...
import { FileUploader } from 'ng2-file-upload';


@Component({
....
...
..
})

export class myFileUploadFormComponent implements OnInit, OnDestroy {

  public uploader: FileUploader = new FileUploader({ url: 
 'http://localhost:3000/files/uploadFile/', itemAlias: 'customerFile' });

 filesArray = [];

 constructor(
    ...
    ..
    private http: Http
 ) { }

 ngOnInit() {
     ....
     ...
     ..
 }

 // INFO: Function for opening confirm modal when deleting file
 openDeleteFileModal(file) {
     const initialState = {
     file: file
     };
 this.deleteFileModalRef = this.modalService.show(ConfirmFileDeletionComponent, { 
 initialState, class: 'modal-md modal-dialog-centered' });
 }

 // INFO: Handy helper for assigning appropriate file-icon according to extension
 getFilesIcon(file) {
    if (file === 'docx') {
       return 'file-word-o';
    } else if (file === 'jpeg' || file === 'jpg' || file === 'png') {
      return 'image';
    } else if (file === 'pdf') {
      return 'file-pdf-o';
    } else if (file === 'xlsx' || file === 'xls') {
      return 'file-excel-o';
    } else if (file === 'pptx') {
      return 'file-powerpoint-o';
    } else if (file === 'zip') {
      return 'file-archive-o';
    } else {
      return 'file';
    }
  }

  /* INFO : service for downloading the uploaded file */
  downloadFile(filename) {
     this.fileDataService.downloadFile(filename);
  }

  onFileChanged(event) {
     this.uploader.onBuildItemForm = (fileItem: any, form: any) => {
     form.append('id', this.customer.id);
     form.append('customername', this.customer.customername);

  };
  this.uploader.uploadAll();
  }

  ngOnDestroy() {
     this.subscription.unsubscribe();
  }
}

Obviously this is my implementation suited to my needs (uploaded files are related to a certain customer and are displayed with icons according to extension and listed for future download or deletion as well), but I'm sure you can get it done by adjusting the code to your needs and write the relevant services. Have a nice one weekend ;)

Upvotes: -1

Žarko Selak
Žarko Selak

Reputation: 1131

This is example of upload method in service. Pass files and input values from component to service, create formData, loop on files and append each file to formData and same with input values.

  upload(files, inputs) {
    let formData  = new FormData();

    files.map((file) => {
      formData.append('file', file);
    });

    inputs.map((input) => {
      formData.append(`${input.name}`, input.value);
    });

    return this.http.post(`some/api/upload`, formData)
      .pipe(map((res) => res.data));

}

With this example your request should contain all array of files and inputs, also if you need some special header add it after formData in post method (in my case i handle headers in interceptor).

  upload(files, inputs) {
    let formData  = new FormData();

    files.map((file) => {
      formData.append('file', file);
    });

    inputs.map((input) => {
      formData.append(`${input.name}`, input.value);
    });

    const headers   = new HttpHeaders({
      'Accept': 'application/json'
    });

    const options = { headers: headers };

    return this.http.post(`some/api/upload`, formData, options)
      .pipe(map((res) => res.data));
  }

Upvotes: 3

Related Questions