无法使用角度为6的反应形式将图像上传到api端点

时间:2018-09-17 05:57:11

标签: angular angular6 angular-reactive-forms

我正在使用Angular 6Reactive Form

我必须上传用户头像图像,为此,我创建了一个具有以下内容的change-avatar组件。

import {Component, OnInit, ViewChild} from '@angular/core';
import {AccountService} from '../account.service';
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';

@Component({
  selector: 'app-change-avatar-modal',
  templateUrl: './change-avatar-modal.component.html',
  styleUrls: ['./change-avatar-modal.component.css']
})
export class ChangeAvatarModalComponent implements OnInit {

  changeAvatarForm: FormGroup;

  @ViewChild('avatar') User_Avatar;
  userAvatarFile: File;

  constructor(
    private accountService: AccountService,
    private formBuilder: FormBuilder
  ) { }

  ngOnInit() {
    this.changeAvatarForm = this.formBuilder.group({
      avatar: new FormControl('', [
        Validators.required
      ])
    });
  }

  get f() {
    return this.changeAvatarForm.controls;
  }

  onSubmit() {
    const image = this.User_Avatar.nativeElement;
    if (image.files && image.files[0]) {
      this.userAvatarFile = image.files[0];
    }
    const avatarFile: File = this.userAvatarFile;
    console.log(avatarFile);

    const formData: FormData = new FormData();
    formData.append('avatar', avatarFile, avatarFile.name);

    console.log(formData);
    const data = {'avatar': formData};

    this.accountService.changeAvatar(data).subscribe(
      res => {
        console.log(res);
      }
    );
  }

}

和在模板文件中

<form [formGroup]="changeAvatarForm" #formDir="ngForm" method="post" (submit)="onSubmit()">

    <input type="file" class="form-control" id="input-avatar" formControlName="avatar" #avatar>
    <button type="submit">Change Avatar</button>

</form>

但是当我使用data发送POST到API端点时。它发送一个空白的avatar字段。

即使请求有效负载中也没有数据。

enter image description here

3 个答案:

答案 0 :(得分:0)

您需要读取文件内容,换句话说,avatarFile变量只是所选文件的句柄,您必须从检索到的文件句柄中读取字节以获取实际文件数据像这样使用FileReader

onSubmit() {
  const image = this.User_Avatar.nativeElement;
  if (image.files && image.files[0]) { 
    this.userAvatarFile = image.files[0]; 
  }
  const avatarFile: File = this.userAvatarFile;

  const fileReader = new FileReader();
  // Do your stuff only after you are done reading the file content
  // Reading starts after this block
  fileReader.onload = () => {
    console.log(avatarFile); 
    const formData: FormData = new FormData(); 
    formData.append('fileName', avatarFile.name);
    // Edited here
    formData.append('fileData', new Blob([new Int16Array(fileReader.result)], {type: 'arraybuffer'});
    console.log(formData);
    const data = {'avatar': formData}; 
    this.accountService.changeAvatar(data)
                       .subscribe(res => { 
                         console.log(res); 
                       });
  };

  // Now actually start reading the file
  fileReader.readAsArrayBuffer(avatarFile);
} 

答案 1 :(得分:0)

您只能传递formData。

onSubmit() {
const image = this.User_Avatar.nativeElement;
if (image.files && image.files[0]) {
  this.userAvatarFile = image.files[0];
}
const avatarFile: File = this.userAvatarFile;
console.log(avatarFile);

const formData: FormData = new FormData();
formData.append('avatar', avatarFile, avatarFile.name);

console.log(formData);

this.accountService.changeAvatar(formData).subscribe(
  res => {
    console.log(res);
  }
);

}

答案 2 :(得分:0)

FileUpload以反应形式,您需要使用$ event获取文件内容

参考:https://medium.com/@amcdnl/file-uploads-with-angular-reactive-forms-960fd0b34cb5

@Component({       模板: <form [formGroup]="formGroup" novalidate (ngSubmit)="onSubmit()"> <input type="file" (change)="onFileChange($event)" /> <button type="submit" [disabled]="formGroup.invalid || formGroup.prestine">Submit</button> </form>     })     出口类PizzaComponent {

  formGroup = this.fb.group({
    file: [null, Validators.required]
  });

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

  onFileChange(event) {
    const reader = new FileReader();

    if(event.target.files && event.target.files.length) {
      const [file] = event.target.files;
      reader.readAsDataURL(file);

      reader.onload = () => {
        this.formGroup.patchValue({
          file: reader.result
       });

        // need to run CD since file load runs outside of zone
        this.cd.markForCheck();
      };
    }
  }

}