1

I got a grid view to display images, I am trying to use the ion-infinite scroll to load more images when the user scrolls to the bottom. I fire an event called "loadMorePosts" which makes an API call gets the next set of images and append it to an array used in the view. My problem is the appended images do not load, seems like the "src" of the ion-img element doesn't get set.

Below is my HTML code

<ion-content>
  <!-- <ion-searchbar showCancelButton="focus" (ionInput)="searchNeighbourHoodWithSearchTerms($event)"></ion-searchbar> -->
  <ion-searchbar #searchBar animated="true" (ionInput)="searchNeighbourHoodWithSearchTerms($event)"></ion-searchbar>
  <ion-slides pager="false" [options]="slideOpts">
    <ion-slide *ngFor="let category of userPreferredBlogCategories;">
      <ion-button id= {{category.categoryName}} class="categoryTabs ion-focused" (click)="searchNeighbourHoodWithCategory(category.categoryName)">{{category.categoryName}}</ion-button>
      </ion-slide>
  </ion-slides>
  <ion-grid>
    <ion-row>
        <ion-col size="auto" *ngFor="let img of neighbourhoodPosts index as i;">
          <ion-img class="neighbourhood-img" [src]="img.blobUrl" (click)="viewdetails(i)"></ion-img>
          <!-- <ion-label style="color: red; margin-top: 20%;">{{img.caption}}</ion-label> -->
        </ion-col>    
    </ion-row>
  </ion-grid>
   <ion-infinite-scroll threshold="100px" (ionInfinite)="loadMorePosts($event)">
    <ion-infinite-scroll-content loadingSpinner="bubbles" loadingText="Loading more data...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>

Below is the method called the ion-infinite-scroll

   async loadMorePosts(evt) {
        setTimeout(() => {
          if (this.currentSearchTerms != null) {
            this.apiHandler.GetNeighbourhoodFeed(this.currentSearchTerms, false, true, "").subscribe((response) => {
              this.neighbourhoodPosts.push(response);
              evt.target.complete();
            });
          }    
        }, 1000);
      }

This is how it appears when new images are pushed to the array

enter image description here

I cannot seem to figure out what causes the new images not to load. Any help would be appreciated. Thank you for your time.

Raju Ahmed
  • 1,282
  • 5
  • 15
  • 24
Troller
  • 1,108
  • 8
  • 29
  • 47
  • try to replace this line `this.neighbourhoodPosts.push(response);` to this line `this.neighbourhoodPosts = [ this.neighbourhoodPosts , ...response ];` and check if it works for you or not? – Developer Nov 14 '21 at 10:46
  • I gave it a shot. It works but it overwrites the array so the view resets, not what I want. Thanks anyways – Troller Nov 14 '21 at 11:18
  • 1
    try to replace `ion-img` with `img` there are some issue with ion-img with infinite scroll – Developer Nov 14 '21 at 11:29
  • 1
    https://stackblitz.com/edit/ionic-angular-v5-pfgpbh?file=src%2Fapp%2Fapp.component.ts try to load data like this as shown in demo, may be its works for you, check this out @Troller – Developer Nov 15 '21 at 10:47
  • 1
    @GaurangDhorda Thanks alot mate, your solution works. I tried changing the ion-img to img as you suggested it doesn't work but your second solution works. I can mark it as the answer if you wanna add it as an answer. Thanks again. – Troller Nov 16 '21 at 08:56

1 Answers1

1

Compelete Demo You can find out in this demo Stackblitz Link

You have to use rxjs subject with rxjs operator function concatemap with scan operator. Basically, initially you call first page api image, and then when user reaches to end position then infinite scroll calls function to load another api image data from server, at that time you simple need to pass info to subject and initial pipe of stream gets called to next chunk of image api data from server.

neighbourhoodPosts = this.page$.pipe(
  concatMap(({ page, limit }) => this.loadImageData(page, limit)),
  scan((acc: any[], items: any[]) => [...acc, ...items])
);

  loadImageData(page, limit) {
    return this.http
     .get(`https://picsum.photos/v2/list?page=${page}&limit=${limit}`)
     .pipe(tap((data) => console.log(data)));
  }

  loadMorePosts(event) {
     this.page += 1;
     this.page$.next({ page: this.page, limit: this.limit });
     event.target.complete();
  }

and this way you only need to subscribe observable from html using async pipe like below...

   <ion-col
      size="auto"
      *ngFor="let img of neighbourhoodPosts | async; index as i"
   >

and rest will works as what your requirement is. Thank You.

Developer
  • 3,309
  • 2
  • 19
  • 23