Angular 7 : How do I submit file/image along with

2019-07-25 18:14发布

I have created simple reactive form with text input and when form is being submitted I want to pass along image from file input. Every time I google I get tutorials, where they show me how I can upload file, but it is being done without other input field. I understand how to do that, what I don't understand how to submit both my form along with file input in one submission.

In my scenario, am I not supposed to user reactive forms and instead simple new FormData() and append every input into that?

If I can do that, leave me simple example.

edit: How to include a file upload control in an Angular2 reactive form? This is not answer. Answer market there is not posting file along with reactive form, it is posting file alone.

2条回答
够拽才男人
2楼-- · 2019-07-25 18:25

Files are binary data, form fields are usually json text files. In order to have them both in one post, you have to convert either one of your data into to other. I did that by converting the file into a base64 string and then adding it to normal json data. Obviously you have to convert the base64 string back into a a file, but most environments (e.g. C#) can do that out of the box.

Here is some code in order to show you how I did that:

Html (this is the file button, you have to use that to make your browser allow you to select a file from file system):

<input name="imageUrl" type="file" [accept]="filePattern" multiple=""
                                (change)="handleInputChange($event)" />

.ts:

    handleInputChange(e) {
    const file = e.dataTransfer ? e.dataTransfer.files[0] : e.target.files[0];
    const reader = new FileReader();

    const fileDto: Partial<IFileSaveDto> = {
        // your other data here
        title: 'what ever here',
        fileAsBase64: null
    };

    reader.onload = (ev: ProgressEvent) => {
        fileDto.fileAsBase64 = reader.result;
    };

    reader.readAsDataURL(file);
}

The disadvantage of that approach is, that base64 generates quite some overhead. If you are uploading very big or many files, that is not a good approach.

Here is a complete, explained example: https://nehalist.io/uploading-files-in-angular2/

查看更多
女痞
3楼-- · 2019-07-25 18:28

Had this issue too, what I did was to construct a FormData, the using a loop add the formGroup values to the form Data

import {
  Component,
  OnInit,
  ChangeDetectorRef
} from '@angular/core';
import {
  FormGroup,
  FormBuilder,
  Validators
} from '@angular/forms';


export class TodoFormComponent {
  todoForm: FormGroup = this.fb.group({
    todo: ['', Validators.required],
    image: ['', Validators.required], //making the image required here
    done: [false]
  })

  constructor(
    private fb: FormBuilder,
    private cd: ChangeDetectorRef
  ) {}

  /**
   *@param event {EventObject} - the javascript change event
   *@param field {String} - the form field control name
   */
  onFileChange(event, field) {
    if (event.target.files && event.target.files.length) {
      const [file] = event.target.files;
      // just checking if it is an image, ignore if you want
      if (!file.type.startsWith('image')) {
        this.todoForm.get(field).setErrors({
          required: true
        });
        this.cd.markForCheck();
      } else {
        // unlike most tutorials, i am using the actual Blob/file object instead of the data-url
        this.todoForm.patchValue({
          [field]: file
        });
        // need to run CD since file load runs outside of zone
        this.cd.markForCheck();
      }
    }

    onSubmit() {
      const formData = new FormData();
      Object.entries(this.todoForm.value).forEach(
        ([key, value]: any[]) => {
          formData.set(key, value);
        }

        //submit the form using formData
        // if you are using nodejs use something like multer
      )
    }

  }
<form [formGroup]="todoForm" (ngSubmit)="onSubmit()">
  <input type="file" formControlName="image" (onchange)="onFileChange($event, 'image')"/>
  <textarea formControlName="todo"></textarea>
  <button type="submit">Submit</button>
</form>

On the server side you can process the request as you would process form-data request

查看更多
登录 后发表回答