如何将具有formgroup值的图像/文件上传到API? [英] How to upload image/file with formgroup value to API?

查看:55
本文介绍了如何将具有formgroup值的图像/文件上传到API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

服务执行http.post时如何上传图像并将其添加到表单中? 示例产品模块需要名称,价格,coverImage. 我尝试使用许多可以从互联网,论坛等处获取的方法. 但是仍然对这个问题一无所知.

我正在使用模型驱动的表单,并在选择图像时将其附加,并且在发送到API之前尝试打印出表单的值. 附加的console.log结果图像:

fyi:我正在使用基于PHP Laravel的API.我试图从"$ request-> file('image');"获取图像

在这种情况下,有人可以帮助我吗? 谢谢.

解决方案

第1部分.通过FormData将文件上传到API

在您的服务文件(如upload.service.ts)中,您需要创建函数以通过POST方法上传文件.这是此功能的示例:

getUploadHeaders() {
    let headers = new Headers({'Accept': 'application/json'});
    headers.delete('Content-Type');
    return headers;
}    

addNewPost(newPost: FormData): Observable<FormData> {
    const endpoint = 'https://yourApiUrl.com'; 
    return this.http
        .post(endpoint, newPost, { headers: this.getUploadHeaders() })
        .catch((e) => this.handleError(e));
}

现在您应该在组件中创建上传功能,例如upload.component.ts.这是使用FormData上传功能的示例.

fileToUpload: File = null;

constructor(private uploadService: UploadService) { }

handleFileInput(files: FileList) {
  this.fileToUpload = files.item(0);
}


saveFileToApi() {
  const saveForm: FormData = new FormData();      
  if (this.fileToUpload) {
    // if you need/want to append other fields to API endpoint
    saveForm.append('name', this.name);
    saveForm.append('link', this.link);
    saveForm.append('description', this.description);
    // if you have to append number
    saveForm.append('age', this.age.toString());
    // append image
    saveForm.append('fileFieldNameOnYourApi', this.fileToUpload, this.fileToUpload.name);
  }

  this.uploadService.addNewPost(saveForm).subscribe(() => {
    console.log('Upload success!');
  }, error => {
    console.log('Upload failed!');
  });
}

saveFileToApi功能中,您还可以附加表格的其他字段.请注意,您应该将数字字段转换为字符串. 此处可以阅读更多有关FormData对象的用法.

要通过FormData上传文件,您需要3个参数:API端点上的propertyName,文件和此文件的名称. 在upload.component.html中,您需要具有如下形式:

<form (ngSubmit)="onSubmit()">     
    <label for="fileField">Chose file to upload</label>
    <input type="file"
           id="fileField"
           name="fileField"
           (change)="handleFileInput($event.target.files)">
    <button type="submit">Speichern</button>
</form>

有关FormData的更多详细信息,请阅读,有关FormData.append()的更多信息,请阅读.

第2部分.从API获取上传的图片

您应该在GET-Request设置中设置responseType: ResponseContentType.Blob,因为这样您就可以将图像获取为blob,并在以后将其转换为base64编码的源.您上面的代码不好.如果您想正确执行此操作,请创建单独的服务以从API获取图像.因为在组件中调用HTTP请求不是很好.

这是一个可行的示例:

在第1部分中创建image.service.ts或使用upload.service.ts(也许您可以给该服务起另一个名字)并输入以下代码:

    getImage(imageUrl: string): Observable<File> {
        return this.http
            .get(imageUrl, { responseType: ResponseContentType.Blob })
            .map((res: Response) => res.blob());
    }

现在,您需要在image.component.ts中创建一些函数以获取图像并将其显示为html.

要从Blob创建图像,您需要使用JavaScript的FileReader. 这是创建新的FileReader并侦听FileReader的load-Event的函数.结果,此函数返回base64编码的图像,您可以在img src-attribute中使用该图像:

imageToShow: any;

createImageFromBlob(image: Blob) {
       let reader = new FileReader();
       reader.addEventListener("load", () => {
          this.imageToShow = reader.result;
       }, false);

       if (image) {
          reader.readAsDataURL(image);
       }
}

现在,您应该使用创建的ImageService从api获取图像.您应该订阅数据并将此数据提供给createImageFromBlob -function.这是一个示例函数:

getImageFromService() {
      this.isImageLoading = true;
      this.imageService.getImage(yourImageUrl).subscribe(data => {
        this.createImageFromBlob(data);
        this.isImageLoading = false;
      }, error => {
        this.isImageLoading = false;
        console.log(error);
      });
}

现在,您可以像这样在HTML模板中使用imageToShow变量:

<img [src]="imageToShow"
     alt="Place image title"
     *ngIf="!isImageLoading; else noImageFound">
<ng-template #noImageFound>
     <img src="fallbackImage.png" alt="Fallbackimage">
</ng-template>

我希望此说明易于理解,并且可以在您的项目中使用.

How to upload image and add it to the form when service doing http.post? example product module needs name, price, coverImage. I tried to use many ways that I can get from the internet, forum, etc. But still got no clue about this issue.

I am using model driven form and append it when image is selected and i tried to print out the values of form before send to API. attached image for console.log result:

fyi: I am using API based on PHP Laravel. I tried to get the image from "$request->file('image');"

anybody can help me for this case? thanks.

解决方案

Part 1. Upload files to API via FormData

In your service file like upload.service.ts you need to create function to upload files via POST method. Here is an example for this function:

getUploadHeaders() {
    let headers = new Headers({'Accept': 'application/json'});
    headers.delete('Content-Type');
    return headers;
}    

addNewPost(newPost: FormData): Observable<FormData> {
    const endpoint = 'https://yourApiUrl.com'; 
    return this.http
        .post(endpoint, newPost, { headers: this.getUploadHeaders() })
        .catch((e) => this.handleError(e));
}

And now you should create upload function in your component, for example upload.component.ts. Here is an example for upload function with FormData.

fileToUpload: File = null;

constructor(private uploadService: UploadService) { }

handleFileInput(files: FileList) {
  this.fileToUpload = files.item(0);
}


saveFileToApi() {
  const saveForm: FormData = new FormData();      
  if (this.fileToUpload) {
    // if you need/want to append other fields to API endpoint
    saveForm.append('name', this.name);
    saveForm.append('link', this.link);
    saveForm.append('description', this.description);
    // if you have to append number
    saveForm.append('age', this.age.toString());
    // append image
    saveForm.append('fileFieldNameOnYourApi', this.fileToUpload, this.fileToUpload.name);
  }

  this.uploadService.addNewPost(saveForm).subscribe(() => {
    console.log('Upload success!');
  }, error => {
    console.log('Upload failed!');
  });
}

In saveFileToApi-function you can also append other fields of your form. Beware that you should convert number fields to string. Here you can read more about usage if FormData Objects.

For uploading an file via FormData you need 3 parameters: propertyName on API endpoint, file and name of this file. And in your upload.component.html you need to have form like this one:

<form (ngSubmit)="onSubmit()">     
    <label for="fileField">Chose file to upload</label>
    <input type="file"
           id="fileField"
           name="fileField"
           (change)="handleFileInput($event.target.files)">
    <button type="submit">Speichern</button>
</form>

For more detail of FormData read this and for more information about FormData.append() read this.

Part 2. Get uploaded image from API

You should set responseType: ResponseContentType.Blob in your GET-Request settings, because so you can get your image as blob and convert it later da base64-encoded source. You code above is not good. If you would like to do this correctly, then create separate service to get images from API. Beacuse it ism't good to call HTTP-Request in components.

Here is an working example:

Create image.service.ts or use upload.service.ts from part 1 (maybe you can give that service another name) and put following code:

    getImage(imageUrl: string): Observable<File> {
        return this.http
            .get(imageUrl, { responseType: ResponseContentType.Blob })
            .map((res: Response) => res.blob());
    }

Now you need to create some function in your image.component.ts to get image and show it in html.

For creating an image from Blob you need to use JavaScript's FileReader. Here is function which creates new FileReader and listen to FileReader's load-Event. As result this function returns base64-encoded image, which you can use in img src-attribute:

imageToShow: any;

createImageFromBlob(image: Blob) {
       let reader = new FileReader();
       reader.addEventListener("load", () => {
          this.imageToShow = reader.result;
       }, false);

       if (image) {
          reader.readAsDataURL(image);
       }
}

Now you should use your created ImageService to get image from api. You should to subscribe to data and give this data to createImageFromBlob-function. Here is an example function:

getImageFromService() {
      this.isImageLoading = true;
      this.imageService.getImage(yourImageUrl).subscribe(data => {
        this.createImageFromBlob(data);
        this.isImageLoading = false;
      }, error => {
        this.isImageLoading = false;
        console.log(error);
      });
}

Now you can use your imageToShow-variable in HTML template like this:

<img [src]="imageToShow"
     alt="Place image title"
     *ngIf="!isImageLoading; else noImageFound">
<ng-template #noImageFound>
     <img src="fallbackImage.png" alt="Fallbackimage">
</ng-template>

I hope this description is clear to understand and you can use it in your project.

这篇关于如何将具有formgroup值的图像/文件上传到API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆