Search code examples
javascriptnode.jsexpressfetchejs

Loading more content from api in Node.js


So I just started learning Node.js and I'm trying to figure out how to load more content on the button click. I think I'm either misunderstanding something or I'm confusing myself.

The code might be a bit of a mess at the moment as I've been trying a bunch of different things.

So far I have a homepage route:

//Home
app.get('/', (req, res)=> {
  res.render('homepage');
});

On the homepage, I have a search bar that calls the /search route with get:

<form action="/search" method="get" id="form">
  <input class="search" name="searchQuery"/>
  <button type="submit">Submit</button>
</form>

Then the search route which makes a call to the API, parses the XML, renders the search page, and sends some data:

//Search
app.get('/search', async (req, res) => {
  g_searchQuery = req.query.searchQuery;
  const fetch_response = async (url, query) => {
    try {
      const response = await fetch(url);
      const xml = await response.text();

      xml2js.parseString(xml, (error, result) => {
        var paginations = result.GoodreadsResponse.search[0];
        totalResults = parseInt(paginations['total-results']);
        resultsEnd = parseInt(paginations['results-end']);

        g_resultsEnd = resultsEnd;

        var test = result.GoodreadsResponse.search[0].results[0].work.map( w => {
          let bestBook = w.best_book[0];
          return {
            title: bestBook.title[0],
            author: bestBook.author[0].name,
            image_url: bestBook.image_url[0],
            small_image: bestBook.small_image_url[0],
            original_publication_year: w.original_publication_year[0]._,
          }
        });

        res.render('search', {data : {
          goodReadsResponse : test, 
          searchQuery : query, 
          totalResults : totalResults,
          resultsEnd : g_resultsEnd,
          currentPage : g_currentPage
        }});
      res.end();
    });
    }
  };

  fetch_response(goodreadsapi + '?key=' + goodreadskey + '&q=' + g_searchQuery + '&page=' + g_currentPage, g_searchQuery);
});

The search page renders the data and has a load more button which with Fetch api makes a call to /search POST:

<body>
<h1>You searched for: <%= data.searchQuery %></h1>

<% if(data.goodReadsResponse) { %>
  <ul class="data-container">
    <%= data.totalResults %>
    <%= data.currentPage %>
    <% data.goodReadsResponse.forEach(function(book) { %>
      <li>
        <span><%= book.title %></span>
        <span><%= book.author %></span>
        <span><img src="<%= book.image_url %>"/></span>
        <span><img src="<%= book.small_image %>"/></span>
        <span><%= book.original_publication_year %></span>
      </li>
    <% }); %>
  </ul>
  <% if(data.resultsEnd <= data.totalResults) { %>
    <div class="load-more__container">
      <button class="load-more__button" type="button">Load More</button>
    </div>
  <% } %>
<% } %>
</body>

<script type="text/javascript">
  window.addEventListener('load', function() {
    const loadMore = document.querySelector('.load-more__button');

    if(loadMore) {
      loadMore.addEventListener('click', (event) => {
        event.preventDefault('Load More');
                    
        fetch('/search', {
          method : 'POST'
        })
      });
    }
  });
</script>

Then this is the part where I get stuck and confused. I have a app.post /search route for the load more button but I'm not sure whats the best way to pass data to that route/if I even need to.

My thinking is that I need to pass most of the data I passed through the render in /search app.get route to the app.post /search route add 1 to the current page, then append the data that I get from the API to the previous data then render the page with that updated data. But I'm slightly stuck.

Here is my repo for this, it's not 1:1 since I tried to clean some things up for the question.

Any help would be greatly appreciated, Thank you.


Solution

  • let bestBook = w.best_book[0];

    In the above line, Considering w.best_book is a list of books, u could just loop it and save all the books in a seperate variable, and render it when Load More button is pressed.