Home > Enterprise >  How to render an Image loaded from postgres Database in angular
How to render an Image loaded from postgres Database in angular

Time:01-03

I'm trying to render dinamically and image linked to an Ad in angular, the problem is that even if in tag the 'src' parameter seems to be right it can't show the image. This is my code in Angular

ngOnChanges(changes: SimpleChanges): void {
    console.log("ngOnChanges: "   changes);
    console.log(this.ads.length);
    for(let i = 0; i< this.ads.length; i  ){
      this.service.getImage(this.ads[i]).subscribe(blobList => this.ads[i].images = blobList).add( () => {
        console.log("Byte: "   this.ads[i].images.at(0));
        let div = document.getElementById("ad"   this.ads[i].id) as HTMLDivElement;
        console.log(div);
        let bytea: ArrayBuffer = this.ads[i].images.at(0) as ArrayBuffer;
        const buffer = Buffer.from(bytea);
        const blob = new Blob([buffer], {type: 'image/png'});
        const image = this.createImageFromBlob(blob);
        div.appendChild(image);
      });
    }
  }


This is the function I use to create an HTMLImageElement from a BLOB


public createImageFromBlob(blob: Blob): HTMLImageElement {
    const image = new Image();
    const url = URL.createObjectURL(blob);
    image.src = url;
    return image;
  }


This is the Ad interface

export interface Ad{
  id: number;
  title: string;
  description: string;
  user: User;
  property: Property;
  price: number;
  mq: number;
  status: string;
  city: string;
  images: ArrayBuffer[];
}

This is my code in HTML


<span *ngIf="!isEmpty()">
  <span *ngFor="let ad of ads">
    <span *ngIf="canShow(ad.status)">
      <div >
        <div >
          <div  style="margin-top: -2%;" id="statusTitle">
              <h2>{{ad.status.toUpperCase()}}</h2>
          </div>
          <div >
              <div  id="ad{{ad.id}}">

              </div>
              <div >
                  <div >
                      <h3 >{{ad.title}}</h3>
                      <p >{{ad.description}}</p>
                      <a href="#"  disabled="disabled">{{ad.price}}</a>
                      <hr>
                      <a href="/profiles/{{ad.user.nickname}}?sessionId={{getSessionId()}}" >{{ad.user.nickname}}</a>
                  </div>
              </div>
          </div>
          <div >
              <a href="/ad/{{ad.id}}?sessionId={{getSessionId()}}" >Leggi annuncio</a>
          </div>
        </div>
      </div>
      <hr>
    </span>
  </span>
</span>

I'm adding the java springboot controller that I use to take data from the database. This method returns a List of Byte[] 'cause I have bytea on postgres database.

@GetMapping("/getImage")
    public List<byte[]> getImage(HttpServletRequest request, @RequestParam String adId){
        List<Image> imageList = DBManager.getInstance().getImageDao().findByAdId(Integer.parseInt(adId));
        List<byte[]> imgList = new ArrayList<>();
        for (Image image : imageList) {
            imgList.add(image.getData());
        }
        return imgList;
    }

And this is the method I use in Angular to call the java server.

 getImage(adId: number): Observable<Blob[]> {
    return this.http.get<Blob[]>('http://localhost:8080/image', {params: {adId: adId}, responseType: 'json'});
  }

As you can see i'm trying to inject the HTMLImageElement in a div linked through an ID.

I tried some other methods but this one is the only that gave me a correct Blob, but on website it only shows the "Image not Found" icon. image

I can't figure out what I'm doing wrong, any help will be very appreciated, thanks.

CodePudding user response:

I resolved ot converting the byte[] to blob but only adding the base64 to image/jpeg encoding string, thank you all, hope this will help someone.

for(let i = 0; i< this.ads.length; i  ){
      this.service.getImage(this.ads[i].id).subscribe(blobList => this.ads[i].images = blobList).add( () => {
        let image = document.getElementById("img"   this.ads[i].id) as HTMLImageElement;
        if(this.ads[i].images.at(0) == null){
          image.src = "https://fakeimg.pl/400x250/?text=No image"
        }else{
          image.src = 'data:image/jpeg;base64,'   this.ads[i].images.at(0);
        }
      });
    }
  • Related