Update Express.JS partial for pagination without affecting URL?

Update Express.JS partial for pagination without affecting URL?
0

#1

I’m currently working on my back-end certification projects and I’ve already submitted the Voting App but I wanted to improve it visually by adding pagination to the section that displays all my polls. Currently I have it setup to display “Top 10 Polls” based on the amount of votes tallied, “Recent Polls” based on creation date, and “All Polls” I want the All Polls partial to include pagination and iterate through every 10 polls.

Onto the problem, I’ve looked at different pagination examples and I have the logic there the only issue is most pagination examples I’ve found require you to have a route similar to this router.get('/poll/:page'... since this particular page has more than one section I’d like a way to iterate through the polls in the All Polls partial without affecting the URL, without having to rely on req.params.page and without having to refresh all data on the page but merely just the partial itself.

I’m sure I can do this using AJAX but I’m unsure if that’s the best way to go about it or where to start? I’m not quite sure how to pass the client side selections (Page 3 out of 10 for example) to the back-end to replace the necessity the current logic has on the req.params.page value. Can anyone assist here and make some suggestions to point me in the right direction?


#2

I see only two options: AJAX, and client side filtering. I think it’s easiest to do the filtering on the client side, but depending on how many polls you expect to have, it could mean transmitting and storing a lot of data. Doing this over AJAX is definitely not difficult, though exactly how you accomplish it will depend on which DBMS you’re using (I’ll assume MongoDB, because this is FCC, but if you’re also using Mongoose it shouldn’t be much different).

Conceptually, a “page” of polls is just X number of items from your database. Let’s set X to be 10. Imagine you have all of your data in an array and you want to get the first page’s worth of data. This is straightforward - all you need to do is get items 0 - 9 (because we’re using zero-based indices). It’s easy to imagine a function which does this with an array:

function getFirstTen() {
    return arr.slice(0, 10);
}

That’s easy enough, but now we want to generalize this so that we can return an arbitrary range of data (20, 25, or 100 instead of just 10) and we want to be able to start from anywhere (this is how we do that pagination).

function getXResults(start, limit) {
    return arr.slice(start, start + limit);
}

Now, if you simply send an array of every single poll to every client, this one function is all you’d need to do pagination on the client-side. But this is possible, maybe preferable, to do over AJAX. Now, MongoDB is of course much different from just manipulating an array, but the idea is the same. We want to pass in the starting index and have some optional limit that tells Mongo how many records we want. This is really easy to do with the cursor methods skip() and limit(). You’ll want a function sort of like this:

function getXPopularResults(start,limit) {
    // use sort() to get a descending order based on the number of responses to the poll
    return db.polls.find().sort({ responses: -1 }).skip(start).limit(limit).toArray();
}

You won’t be able to drop this code into your project and have it work, but I think you’ll get the idea. If you want, you can create a convenience function to return the top 10 most popular:

function get10MostPopular() {
   return getXPopularResults(0, 10);
}

If you’re using Mongoose, the concept is the same, but I don’t know how to do skip and limit off the top of my head (easy to find, I’m just lazy). As a side note, if you do a search on the topic of pagination in MongoDB, you’ll see a prominent StackOverflow answer which says not to use skip because it doesn’t scale well. You can ignore this for now since you’re probably not going to have millions of polls in your DB, but it’s an important point to keep in mind.