Search code examples
angularamazon-web-servicesposthttprequest

how do I send a image as binary data to my API using angular?


I am trying to make a angular request based on a curl request, this one:

 curl -k -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/octet-stream" --data-binary '@/home/linux-user/Desktop/folder/cool-folder/src/assets/img/default-image.png' -X POST https://$ENDPOINT:6060/v1/user/photo\?id\=3591\&image\=996ab426-eb57-4f79-94f4-cfea9aef2cd9 |  gunzip | jq

*FYI: The request is successful but the image arrives corrupted, also I am sending the image to AWS through an api

ImageService:

  private postHeaders(token: string): HttpHeaders {
      return new HttpHeaders({
        'Content-Type': 'application/octet-stream',
        Authorization: `Bearer ${token}`
      });
    }

uploadImage(file: File, token: string): Observable<any> {
      const headers = this.postHeaders(token);
  
      const formData = new FormData();
      formData.append('file', file);
  
      return this.http.post(this.endpoint, formData, { headers, responseType: 'text' })
        .pipe(
          map((response: any) => JSON.parse(response)),
          catchError((error: any) => throwError(error))
        );
    }

Component

onFileChange(event: any) {
    const file = event.target.files[0];
    console.log(file)
    if (file) {
      this.imageService.uploadImage(file, this.token)
        .subscribe((response) => {
          console.log(response); // Handle the response data here using 'jq' or other methods.
        }, (error) => {
          console.error(error);
        });
    }
  }


console.log(file)

Another example of the component above

tried binary

 onFileChange(event: any) {
    const file = event.target.files[0];
    console.log(file)
    if (file) {
      this.readFileContent(file);
    }
  }

  readFileContent(file: File) {
    const reader = new FileReader();

    reader.onload = (e: any) => {
      const binaryData = e.target.result; // This contains the binary data of the file

      this.imageService.uploadImage(new Blob([binaryData]), this.token)
        .subscribe((response) => {
          console.log(response); // Handle the response data here
        }, (error) => {
          console.error(error);
        });
    };

    reader.readAsArrayBuffer(file);
  }

Html

<input type="file" (change)="onFileChange($event)">

Solution

  • Apparently, simply passing file is supposed to work, according to that: http://www.sibenye.com/2017/02/17/handling-image-upload-in-a-multitiered-web-application-part-1/

    FormData must better be used to send multipart/form-data.

    onFileChange(event: any) {
        const file = event.target.files[0];
        console.log(file)
        if (file) {
          this.readFileContent(file);
        }
        
        // part to send data
        let url = '/url';
        let headers = new Headers();
        headers.set('Content-Type', 'application/octet-stream');
        headers.set('Upload-Content-Type', file.type)
        // add authorization etc too
        let options = new RequestOptions({ headers: this.headers });
        this.http.post(url, file, options).subscribe()
      }