1

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 class="container justify-content-center">
        <div class="card jumbotron">
          <div class="text-center badge-info badge" style="margin-top: -2%;" id="statusTitle">
              <h2>{{ad.status.toUpperCase()}}</h2>
          </div>
          <div class="row no-gutters m-3">
              <div class="col-lg-5 col-md-7 col-md-12" id="ad{{ad.id}}">

              </div>
              <div class="col">
                  <div class="card-block px-2">
                      <h3 class="card-title">{{ad.title}}</h3>
                      <p class="card-text">{{ad.description}}</p>
                      <a href="#" class="btn btn-primary" disabled="disabled">{{ad.price}}</a>
                      <hr>
                      <a href="/profiles/{{ad.user.nickname}}?sessionId={{getSessionId()}}" class="card-text text-dark">{{ad.user.nickname}}</a>
                  </div>
              </div>
          </div>
          <div class="card-footer w-100 text-muted">
              <a href="/ad/{{ad.id}}?sessionId={{getSessionId()}}" class="btn btn-lg btn-outline-primary btn-block">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.

2
  • Just Tested your code. If I generate a correct blob, then the image will be displayed. So check the steps before converting the image to blob. What does your this.service.getImage(this.ads[i]) do exactly? Commented Jan 1, 2023 at 16:29
  • getImage is the method I use to retrieve the Blob from database, it returns Observable<Blob>, my java servlet (mapped to "/getImage") instead returns a byte[] couse I'm using a postgres database and it takes byte[] as blobs, at least is what i found. Am I doing anything wrong? I edited the main form so you can read my methods. Commented Jan 2, 2023 at 14:40

1 Answer 1

1

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%20image"
        }else{
          image.src = 'data:image/jpeg;base64,' + this.ads[i].images.at(0);
        }
      });
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.