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.
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.