Save 36% for Black Friday! Learn more

Darin Haener

Joined

10 Experience
0 Lessons Completed
0 Questions Solved

Activity

This is awesome Chris! I noticed that on mobile browsers the scroll handler is called multiple times, resulting in multiple network requests and several duplicate pages being loaded and appended. If anyone else runs into this, adding a simple loading state to the controller can fix this:

export default class extends Controller {
  static targets = ['entries', 'pagination'];

  initialize() {
    this.loading = false;
  }

  scroll() {
    const nextPage = this.paginationTarget.querySelector("a[rel='next']");

    if (nextPage == null) return;

    const url = nextPage.href;
    const body = document.body;
    const html = document.documentElement;
    const height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);

    if (window.pageYOffset >= height - window.innerHeight - 500) {
      if (this.loading) return;

      this.loadMore(url);
    }
  }

  loadMore(url) {
    this.loading = true;

    Rails.ajax({
      type: 'GET',
      url,
      dataType: 'json',
      success: data => {
        this.entriesTarget.insertAdjacentHTML('beforeend', data.entries);
        this.paginationTarget.innerHTML = data.pagination;
        this.loading = false;
      }
    });
  }
}

Just create a global this.loading variable on initialize and set to true in the loadMore method, then set to false after a successful load and voila!