Ion-infinite-scroll not firing ionInfinite if records do not fill the page

ion-infinite-scroll does not fire the ionInfinite event if my initial retrieval of records does not fill the page.

I retrieve a batch of 10 records at a time and if I’m running the app in a full-screen browser this initial batch of records only fills about half of the infinite scroll area. I was expecting ionInfinite to be called to retrieve a second batch of records to fill the area (or be told that there are no more records).

If I shrink the window so that the area shows scrollbars then ionInfinite is called when the user scrolls down.

The user should not have to resize the window to get a full page of records.

There is an open issue for this from Ionic v3 Issue #59.

No solution, only workarounds that dig into the internals of the control which I’m loath to do given we are now at Ionic v5.

Is this issue being worked on?

Does anyone have a working workaround for v5?

Thanks.
Glenn.

Bump.

Others must have hit this problem.

I can increase the number of records I retrieve per page to fill all form factors, but I’m using Firebase and this would be an increase in costs to work around a bug in Ionic.

Hi Avaxa,

I did have the same issue and created the following work-around.
It seems to work correctly, but I still have the feeling that I am missing something obvious. I think this should be working out of the box.

However, I hope it might be useful to you.

regards, Theo

export class MyInfiniteListComponent<T> {
  data: T[] = [];
  isLoading = false;
  nextPage: number;
  private subscription: Subscription;

  protected service: MyDataService<T>;
  @ViewChild(IonContent, {static: false}) private content: IonContent;
  @ViewChild(IonInfiniteScroll, {static: false}) infiniteScroll: IonInfiniteScroll;

  @HostListener('window:resize', ['$event'])
  onResize() {
    this.fillPage();
  }

  resetView() {
    this.isLoading = false;
    this.data = [];
    this.nextPage = 0;
    this.infiniteScroll.disabled = false;
    this.loadData(true);
  }

  loadData(initial=false) {
    console.log('loadData:');
    if (this.isLoading) {
      console.log('still loading');
      this.infiniteScroll.complete();
      return;
    }

    const state = {} as ListStateModel;
    state.pageNumber = this.nextPage;
    state.pageSize = 10;
    this.nextPage += 1;
    this.isLoading = true;
    this.service.list(state).subscribe( result => {
      this.isLoading = false;
      this.data = [
          ...this.data,
          ...result.items,
      ];

      if (result.count === 0) {
        this.infiniteScroll.disabled = true;
      } else {
        if (initial) {
          this.fillPage();
        }
      }
      this.infiniteScroll.complete();
    });
  }

  fillPage() {
    this.checkForScrollbar().then(res => {
      if (!res) {
        console.log('no scrollbar, trying to load more data');
        this.loadData(true);
      }
    });
  }

  ionViewWillEnter() {
    this.resetView();
  }

  doRefresh(event) {
    this.resetView();
    event.target.complete();
  }

  async checkForScrollbar() {
    const scrollElement = await this.content.getScrollElement();
    return scrollElement.scrollHeight > scrollElement.clientHeight;
  }
}

Thanks Theos. I’ll try your workaround and appreciate you taking the time to reply.

I currently set my pageSize to something large enough to get a full page of records. It works but retrieves more data than strictly necessary.