AJAX Loading with Tag Filter

This issue probably doesn’t really belong here but since it’s based off this cookbook recipe, i figured a solution might be useful to others, too.

I have tried to add tag filtering to the example but I’m having trouble with the load more JavaScript (standard pagination works fine).

Here’s the JSON controller:

<?php

return function ($page) {

  $limit      = 2;
  $articles = $page->children()->listed()->flip();

  if($tag = param('tag')) {
    $articles = $articles->filterBy('tags', $tag, ',');
  }

  $articles = $articles->paginate($limit);

  $pagination = $articles->pagination();

  $more = $pagination->hasNextPage();

  return [
      'articles' => $articles,
      'pagination' => $articles->pagination(),  
      'more'     => $more,
      'html'     => '',
      'json'     => [],
    ];
};

The markup:

<ul class="news-listing" data-page="<?= $pagination->nextPage() ?>" data-tag="<?= param('tag') ?>">
  <?php foreach ($articles as $article): ?>
    <?php snippet('news-item', ['article' => $article]) ?>
  <?php endforeach ?>
</ul>

and the JavaScript:

const newsListing = document.querySelector('.news-listing');
const button = document.querySelector('.load-more');

if (newsListing && button) {

  let page = parseInt(newsListing.getAttribute('data-page'));
  let tag = parseInt(newsListing.getAttribute('data-tag'));

  const fetchArticles = async () => {
    let url = `/newsroom.json/page:${page}`;

    if (tag) {
      url = `/newsroom.json/tag:${tag}/page:${page}`;
    }

    try {
      const response = await fetch(url);
      const { html, more } = await response.json();
      button.hidden = !more;
      newsListing.innerHTML += html;
      page++;
    } catch (error) {
      console.log('Fetch error: ', error);
    }
  }

  button.addEventListener('click', fetchArticles);

}

I’m pretty sure I’m missing something on the JS side of things. Any help is appreciated.

D’Oh! Trying to convert a tag to an integer is probably not the best idea…

Replaced:

  let tag = parseInt(newsListing.getAttribute('data-tag'));

with:

  let tag = newsListing.getAttribute('data-tag');

and all is good.