0

Network request shows that the images are returning to frontend (ANGULAR 13) from NestJs server, but the type is text/html with 200 status and initiator:platform-broweser.mjs. There is no error on console.The image path is stored in MongoDb and path is attached with product.I want to convert that text/html response into actual image that is uploaded to server and make the images visible as the products with details are visible but images are not visible.'

Here Showing all the products

BookForm = new FormGroup({
    _id: new FormControl(''),
    name: new FormControl(''),
    author: new FormControl(''),
    price: new FormControl(''),
    genres_name: new FormControl(''),
    coverimage: new FormControl(''),
  });

  results?: Book[];

  constructor(
    private readonly apiService: ApiService,
    private router: Router,
  ) {}

  ngOnInit() {
    this.apiService.getallbooks().subscribe((data: Book[]) => {
      this.results = data;
    });
  }

Showing All products html

<div class="grid" *ngFor="let result of results">
      <div class="blog-card spring-fever" style="padding: 0.5rem; z-index: 100">
        <img
          class="image"
          src="http://localhost:3000/{{ result.coverimage }}"
          alt=""
          height="400px"
          width="250px"
          style="border: 1px solid red"
        />

Angular file upload encoded base64

imagedata?: string;

async uploadimage(event: any) {
    const file = event.target.files[0];
    this.AddbookForm.patchValue({ coverimage: file });
    const allowedMimeTypes = ['image/png', 'image/jpeg', 'image/jpg'];
    this.AddbookForm.get('coverimage')?.updateValueAndValidity();
    if (file && allowedMimeTypes.includes(file.type)) {
      const reader = new FileReader();
      reader.onload = () => {
        this.imagedata = reader.result as string;
      };
      reader.readAsDataURL(file);
      console.log(file);
    }
  }
M Nouman
  • 437
  • 1
  • 5
  • 22

2 Answers2

0

By default, the response type of any HTTP call in Angular is of type JSON. You will need to explicitly tell Angular of the response type. Use responseType as blob to achieve this.

For instance:

this.httpClient.get('url', params,
  {
    observe: 'response',
    responseType: 'blob'
  });
Aman
  • 33
  • 7
  • But I don't have any params in my Angular get request. Let's suppose I create a parameter of params what will be the type? – M Nouman Jul 30 '22 at 18:44
  • No worries, just remove the params part like below: this.httpClient.get('url', { observe: 'response', responseType: 'blob' }); – Aman Jul 30 '22 at 18:47
  • I'm implementing this logic in my api.service file's Get methode. Where I'm getting the entire product. AND it's giving this error`No overload matches this call.` on `responseType:'blob`. – M Nouman Jul 30 '22 at 18:51
  • my Get request function in api.service is of `Observable` type. – M Nouman Jul 30 '22 at 19:00
  • Could you remove the type from Get request and try again? And after getting the blob you will need to use FIleReader to create the image from it. Please refer to: https://stackoverflow.com/questions/45530752/getting-image-from-api-in-angular-4-5 – Aman Jul 30 '22 at 19:14
  • first my call was like this `get`. when I did like this `get`. The error was gone but the console showed the error `Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays`. Second if I remove from Observable or even the entire Observale thing It gives me errors in `ngOnInIt` as I'm subscribing data there. – M Nouman Jul 30 '22 at 19:18
  • Ok I followed the link, but that is just for the image, and here I'm dealing with an entire product, and the image path is attached with the product. Now when I pass the subscribed data to the function that is converting `ImageFromBlob`, as parameter,it gives me the error `(parameter) data: Book[] Argument of type 'Book[]' is not assignable to parameter of type 'Blob'`.I used `data.map((item))`, to get image value, it throws another error`Argument of type 'void[]' is not assignable to parameter of type 'Blob'.` – M Nouman Jul 30 '22 at 19:37
0

The actual issue here was not the type,the actual issue was in my URL.I had a folder in NestJs server by the name of assets,that is present at root, and I had set the path for the images(in NestJs file upload code), like this ./assets/. That is also the correct way to set the destination folder.I was able to see the images at browser like this http://localhost:3000/imagename.png,and that means my server configured to server/serve my images over root URL that's why I can access them http://localhost:3000/imagename.png. But my api was returning images in a format that contains ./assets/ in the URL. So with the following code

<div *ngIf="result.coverimage">
          <img
            class="image"
            src="http://localhost:3000/{{ result.coverimage }}"
            alt=""
            height="400px"
            width="250px"
            style="border: 1px solid red"
          />
        </div>

I am assuming that I'm hitting the Url like this http:localhost:3000/imagename.png with pipe safurl to sanitize and tell Angular that this url is safe. But actually Angular was seeing the URL like this http:localhost:3000/./assets/imagename.png. And this is note the correct URL Format. Urls don't work with . or ,.Also becasue my server is configured at root, this urlhttp;//localhost:3000/assets/imagename.png is also wrong.And root means that, whatever the thing is set at root, that is directly access able after your server's port number. Example http://localhost:YourServerPortNumber/TheThing_Set_at_Root.

So the solution for this issue is the following

src="http://localhost:3000/{{
              result.coverimage.replace('./assets/', '')
            }}"

And also this

<div *ngIf="result.coverimage">
          <img
            class="image"
            src="http://localhost:3000/{{
              result.coverimage.replace('./assets/', '')
            }}"
            alt=""
            height="400px"
            width="250px"
            style="border: 1px solid red"
          />
        </div>

With above .replace('./assets/', '') we are removing the ./assets/ and repalcing it with '' empty space. So now URL is in this formathttp://localhost:3000/imagename.png.

M Nouman
  • 437
  • 1
  • 5
  • 22