Search code examples
angulartypescriptresponseconsole.log

Angular displaying REST Response after file upload


I have an angular application and I want to upload a file and display a string based on the uploaded file. I make a post call to a Rest API, this API returns a Response and I want to display the content of this response. Something is wrong however because I can console.log the content of the response but I fail to display it normally (i.e as a label or similar).
Can anyone please tell me how to do that?

Here is component.html

<div>
    <label class="image-upload-container btn btn-bwm">
        <span>Select Image</span>
        <input #imageInput type="file" accept="image/*" (change)="processFile(imageInput)">
    </label>

    <!--IT DOES NOT WORK  Displays [object Object] -->
    <input type=text name="prediction" [(ngModel)]="prediction" />

    <!--IT DOES NOT WORK  Displays [object Object] -->
    {{prediction}}
</div>

here is component.ts

import { Component, OnInit } from '@angular/core';
import { ImageService } from '../../services/image.service';

class ImageSnippet {
  constructor(public src: string, public file: File) { }
}

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

  constructor(private imageService: ImageService) { }
  prediction!: String;
  ngOnInit(): void {
  }
  processFile(imageInput: any) {
    const file: File = imageInput.files[0];
    const reader = new FileReader();

    reader.addEventListener('load', (event: any) => {

      let selectedFile = new ImageSnippet(event.target.result, file);
      this.imageService.uploadImage(selectedFile.file).subscribe(
        (response) => {
          
          this.prediction = response.toString();// IT DOES NOT WORK  Displays [object Object] 
          // console.log() WORKS: it logs something like this: {prediction: "jeges, tensor([0.0530, 0.0999, 0.8471])"}
//which is the exact string that I want to display
          console.log(response)
        }        
    });
    reader.readAsDataURL(file);
  }
}

here is service.ts

...
uploadImage(imageFile: File): Observable<Response> {
    const formData = new FormData();
    formData.append('imageFile', imageFile);
    return this.http_client.post<Response>(this.url, formData);
  }
...

and here is the API:

@app.route('/api/image-upload', methods=['POST'])
def call_predict():
    imageFile = request.files['imageFile']
    prediction = makePrediction(imageFile)
    resp = make_response({"prediction": prediction}, 200)
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp


Solution

  • you have a toString() call on your response, which is causing the string on display. So let us begin by fixing your file handler function right:

    So start by fixing you service request handler like this

    this.imageService.uploadImage(selectedFile.file).subscribe(
      (response) => {
        this.prediction = response;
      }        
    });
    

    So this change will cause problems in your HTML so we need to adjust that because this.prediction isn't a string

    <div>
        <label class="image-upload-container btn btn-bwm">
            <span>Select Image</span>
            <input #imageInput type="file" accept="image/*" (change)="processFile(imageInput)">
        </label>
    
        <!-- here we'll bind according to the structure you gave in your code -->
        <input type=text name="prediction" [(ngModel)]="prediction.prediction"/>
    
        <!-- Since we have an object we cant just dump it here, so lets use a json pipe -->
        {{prediction | json}}
    </div>
    

    Lastly the member prediction in your class has to be type Response

    prediction!: Response;
    

    So this should work I think, try it out...