1

I have a function that loads product data from a database. This data will be loaded into html using * ngFor.

After uploading the data, I intend to upload the image for this product ID. That is, I try to pass the product ID and I have perform the function of getting images, with id I get.

The problem is that * ngFor goes into a continuous loop and neither images load :(

The problem will be in this line, because if the comment code runs without any infinite loop. (of course not upload images):

<img *ngIf="inView" [src]="ImageInfo(product.id)"  class="Images img-fluid" alt="" (click)="fillModal($event)"> 

HTML

<div class="container-fluid first" style="cursor: pointer;" data-toggle="modal" data-target="#modalPoll">
      <div class="row tab-pane Galeria">
        <div *ngFor="let product of products" class="col-xl-2 col-lg-3 col-md-4 col-sm-6">
          <div class="image-item">
            <homeImage>
              <a class="d-block image-block h-100">
                <img *ngIf="inView" [src]="ImageInfo(product.id)"  class="Images img-fluid" alt="" (click)="fillModal($event)"> 
              </a>
            </homeImage>
            <div class="ImageText"> {{product.name}}</div>
          </div>
        </div>
      </div>
    </div>
Harry
  • 621
  • 3
  • 9
  • 21
  • Could please post your component class? – Rafi Henig Nov 14 '19 at 09:39
  • @RafiHenig I put in the post the link of my code (stackblitz), there you find everything I'm using – Harry Nov 14 '19 at 09:47
  • You should completely restructure your code and fetch all the products and image for all products before showing in template: https://stackoverflow.com/q/37876533/6294072 – AT82 Nov 14 '19 at 10:49
  • @AJT82 I think this is the problem. I only use the homeImage model to load the images as I scroll .... I can't solve the problem :( – Harry Nov 14 '19 at 10:53
  • Please edit your stackblitz link – keser Nov 16 '19 at 11:35

3 Answers3

0

I'll give it a try. It might not be the answer but if I'm not mistaken you have a flaw in your img source: [src]="ImageInfo(product.id)".

Here your code doesn't return anything:

ImageInfo(id) {
      var self = this;
      self.Global.refreshToken().subscribe(function (result) {
        self.homeService.getImage(id).then(function (resultado) {
          if (resultado) {
             self.Imagenss = resultado;
          }
        }).catch();
      });
    }

So there's no source. You're just assisgning the "imagenss" variable the result of your request.

I can't test it but you might need to do something like:

ImageInfo(id) {
      var self = this;
      self.Global.refreshToken().subscribe(function (result) {
        self.homeService.getImage(id).then(function (resultado) {
          if (resultado) {
             self.Imagenss = resultado;
             return self.Imagenss; // <---- HERE RETURNING WHAT I ASSUME TO BE THE PATH
          }
        }).catch();
      });
    }
Martin Carre
  • 1,157
  • 4
  • 20
  • 42
  • I had already tested this and it didn't work, it's still in an endless loop of service requests :( – Harry Nov 14 '19 at 10:02
0

Structurally some things need to be re-ordered. Try fetching all the data you need from the API in your ngOnInit():

ngOnInit() {
  this.GetProducts();
  this.GetAllImageInformation();
}

The culprit line that probably hangs is this one:

<img *ngIf="inView" [src]="ImageInfo(product.id)" class="Images img-fluid" alt="">

By calling a function inside [src], this function will execute whenever data is updated. Since the backend triggers a data refresh, it will then call the function again etc. etc.

Try structure your code in a way to first fetch all your data and try to pass a string with the location of the image to [src]. This will most likely solve your problem.

Rutger van Dijk
  • 330
  • 1
  • 9
0

It seems that it is better to change your approach to get images. Instead of getting them in ngFor, it is better to get all images on initialization and populate them in your template:

allImagesLoaded = false; // variable to show whether images are loaded
getImages(productIds) {
    // your aPI method that returns images. Result depends on your server i.e. base64 data, image url

    this.allImagesLoaded = true; 
}

and then render all your images:

<ng-container *ngIf="allImagesLoaded ">
    <div *ngFor="let product of products" class="col-xl-2 col-lg-3 col-md-4 col-sm-6">
      <div class="image-item">
        <homeImage>
          <a class="d-block image-block h-100">
            <img *ngIf="inView" [src]="ImageInfo(product.id)"  
                class="Images img-fluid" alt="" 
                (click)="fillModal($event)"> 
          </a>
        </homeImage>
        <div class="ImageText"> {{product.name}}</div>
      </div>
    </div>
 <ng-container>

or if your count of images not so many, then you can include your images into your project and use it in img tag:

<img [src]="imagePath" />
StepUp
  • 36,391
  • 15
  • 88
  • 148