Placeholder Image

Subtitles section Play video

  • Hello, everyone.

  • In today's video, we're gonna look at pagination, which is the ability to return just a subset of the results from your A p I to the users so that they can go page forward or Paige back, just the same as how Google search works.

  • And we're gonna tackle this in three different ways.

  • First, we're gonna build just the most basic pagination that you can build inside of an A p I.

  • Secondly, we're gonna take that a step further, and we're gonna make a nice middle where for a pagination so we can apply it to any of the resource is in our a p I.

  • And then third, we're gonna hook up this simple section of our pagination to a database that we actually have a real world mongo D B database that we can paginated with our A.

  • P.

  • I was get started.

  • Now, as always, I just have a completely blank folder open in visual studio code, and the very first thing we need to do is to run N p m on it with the dash.

  • Why is the flag and this is going to initialize the repositories with a package da Jason.

  • Next we need to install the dependencies we're gonna use.

  • And since we're going to use this server, we need to install Express, which is going to be the framework for our server.

  • Also, we're gonna install a dead dependency by typing and dash dash save, Dev, And this is going to be for node mon.

  • And what Node Mon allows us to do is it automatically refreshes our server every single time we make changes.

  • This way, we don't have to manually stop and start our server every time we make changes now in the package dot Jason, in order to use Node mon, I was just create a simple script.

  • We're gonna call it Deb start and inside this script, we just want to put no daemon.

  • And we want to put our server dot Js file just like this and this is going to be a file that we're gonna create now.

  • So let's create that server dot Js and this is going to be where all of our server code goes.

  • So let's just make sure we save our package, Jason and then inside of our server dot Js, let's set up the most basic express server we can.

  • So we want our express variable which we could get from the express library.

  • We could just say require express And then we also want to get the app portion of that which is just calling this express function flips just like that.

  • And then lastly, we can just say ap dot Listen, and we can give it a port, for example Port 3000.

  • And now if we come down here and we type and PM run Dev start, which is that command we just created, you'll see that our server is gonna start up and you say it's starting note server dot Js and our application is listening on Port 3000 and this is great, But right now, we aren't doing anything with this server.

  • So let's set up our very first route, which is going to be getting a list of users.

  • We can do that very simply by saying app dot get and we want to get users so we could just say slash users.

  • And of course, we have a request and our response variable.

  • And in here we just want to return our users so we could just say, responsive dot Jason, we want to return users, so let's just create that users variable.

  • And as I mentioned at the beginning of this video, the very first step is just a very simple pagination.

  • We're not gonna worry about the database that's going to come later in the video.

  • So for now, we're just gonna create a user's variable.

  • And we're gonna set this tour own array and inside of here, what's put our user objects.

  • So our users are goingto have, Let's say an I d of one and we're gonna give them a name, for example user one.

  • And now I'm just gonna copy this down a bunch of different times so we can simulate having a bunch of users.

  • I'm just gonna income in all of these numbers just like this.

  • 10 11 12 13 and same thing for the names of the users.

  • Just get all this out of the way.

  • 10 11 12 13.

  • Perfect.

  • Now, if we go down here, save this, you see our application restarted and we can create a file over here, which is gonna be called request dot rest.

  • And I'm using an extension in visual studio code this extension here is called Where can rest client right here.

  • And this allows me to make rest request inside of a file called dot rest, for example, we can say that we want to get at a local host 3000.

  • Make sure you put http at the beginning slash Slash and we want to get slash users just like that and you see the center request button.

  • If I click that, you'll see it makes the request over here.

  • As you can see, we get our list of users return to us in Jason, so we know their application is actually working.

  • What's minimize all this?

  • Go back to our server so we know that our users is working.

  • But we actually want to be able to pass what Paige and what offset we want so that we could get on Lee.

  • The resource is we want and not the whole list because you can imagine this close could be thousands of users long, and we don't want all the users every single time.

  • So, for example, let's look at our request here, and maybe we want to build a pass.

  • Some resource is, for example, we want to be able to pass that we want to have a page, Let's say, for example, page one and we also want to pass a limit.

  • What say that?

  • We want the limit here just to be five, for example.

  • So it's the same.

  • Give me the first page of users and I only want five users from that page.

  • Obviously, right now, if we send that request, we still get all the users.

  • It's not actually doing anything.

  • So let's go into our server and start implementing this.

  • So inside of this get users function we want to build to get those variables we just passed up.

  • So we have our page, which is equal to request Doc.

  • Query got Paige and the exact same thing for that limit.

  • Variable.

  • Now we're actually processing this page and limit request that's being sent up to us, and all we need to do is actually get the array that we're returning right now, which is all of our users, and condense that toe only the specific page and the specific users in that limit range.

  • And the easiest way to do that is to get this START index and the end index of where we're going to be QUERIAN and start indexes, actually fairly simple over doing is taking our page minus one, and we're just multiplying.

  • It flips times our limit.

  • So what it's saying is we know that our page that we're on is going to be a page we want.

  • For example, one is going to be a page one page to his page, too.

  • But since a raise our zero indexed and these pages are one indexed, we need to make sure we subtract one.

  • Because Page one is essentially the same as starting a Index zero insider application.

  • So one minus one would be zero times our limit.

  • We start at Index zero now moving on to the end index.

  • This is just going to be a page times limit because we don't need to worry about subtracting one, since we want to get the very end of our array and not the beginning of it.

  • So now that we have our Start Index and our end index we can do is actually query our users to return just the users in between the start and end index, and that's actually fairly straightforward.

  • Well, we need to do is say, users dot slice and the slice method.

  • We pass it a start and an end number and it gives us everything between those So we can just say Start index and End Index.

  • And we could just use this as a result.

  • So we could just set this to result users and let's actually return.

  • That is our Jason.

  • Now let's make this request again and you can see we get users.

  • 1234 and five These air just our 1st 5 users.

  • If we change our page to page to make a request, You see, we get the next five, we get six through 10 and we could maybe change this to be a limit of three.

  • And now if we make the request, you see, we get 456 which is the second page, if you limit by three.

  • And now this is all great.

  • But usually when you have a paginated a p I, you actually want to return somewhere inside that a p I what the next page would be and the previous page so that the user knows if there is a next page or if there isn't a next page and same thing with previous page.

  • It just makes it easier for the client consuming the AP.

  • I So in order to do this, we actually want to upend extra results to here.

  • So it's create another very book.

  • What is gonna call this results?

  • And we're gonna set it to an empty object.

  • And then our result users were just gonna save results.

  • Dot results is going to be equal to thes users, and then we want to return our results.

  • So now in our request, if we make this again, you see, we have a result section which is going to return our array of users and I we can actually put extra information inside of our object for the next and the previous pages.

  • So let's do that now what set up next?

  • So we can say results dot next, and this is just going to be equal to empty her an object.

  • And the object is goingto have a page as well as a limit property.

  • And now the limit property is going to stay exactly the same.

  • We're just gonna pass the limit they passed us.

  • But as for the page, we actually want to pass the next page.

  • So we could just say Paige plus one.

  • And we could do the same exact thing for previous.

  • And as you guessed that, we just want to do Paige minus one.

  • So, Paige, minus one.

  • We want this to be previous.

  • So now if we do our request again, you see, we haven't next, which is saying Page 21 this is actually problem.

  • If we go back to our server, this is being passed up as a string.

  • Same with the limit.

  • So we want to actually parse this as an ent.

  • So you just say person and we can do the exact same thing with our limit.

  • So we want to parse.

  • That is an imager.

  • Now, if we say this, make a request.

  • You'll see there are pages.

  • Three are limits.

  • Three previous pages, one and three.

  • Now, this works great.

  • But what if we changed page one?

  • If we make a request, you're going to see our previous is paige zero.

  • And obviously this is not valid.

  • There is no Page zero, so we need to make a couple checks inside of our server.

  • We'll start with the previous one.

  • First, we want a check to see if we have a previous page, and this is pretty easy.

  • We just want to see if the start index is greater than zero.

  • Because this means that are ready Here is not starting at the very first user.

  • Also, for our next results, we could do a very similar thing.

  • We just want to check if our index is less than our users dot length and we could put this inside of here.

  • So what this is saying is that our end is somewhere before the end of our actual users or Ray, so we have extra users to query, so we should show them the next.

  • And now if we send a request, you see the previous section goes away.

  • But let's say if we make argument here to be 13 for example, now, if we save this click send request, you see that immediately our next and previous go away because there is no next or previous section that we could go to.

  • We could even change this down to 10 for example, Save make a request and you can see now next actually shows up as a result because we have a next page.

  • Since we have more than 10 users.

  • Now, this is the very basics of how to set a pagination.

  • But we have to copy this code every time we want to paginated a different user.

  • Let's say we have a different model was just copy this and what's say we have post and we're gonna change here, User to be post for all these.

  • Just excuse all this.

  • So now we have two different models.

  • We have a post model and a user model and we wanna have a nap dot Get for the post so we can come in here post and, of course, request response.

  • Now, in order to set this up, we'd have to copy all this code like this and pasted inside a post and change all of our user variables such as here.

  • Change those two post and that sounds like a lot of work.

  • So instead, what we want to do is set up some form of middle where were essentially All we do is pass it up here.

  • We can say paginated results, and all we would do is pass it part post.

  • And this would actually do all of the pagination for us.

  • We wouldn't need to do anything ourselves.

  • So in order to do that, we need to create a function that will handle that.

  • So it's remove all this code instead of here.

  • We don't need anything instead of our post.

  • It would just be completely empty for now, just like that.

  • Perfect.

  • Now let's go all the way down, create that function, what's function.

  • We're gonna call it paginated results and this is going to take the model that we want to paginated and now inside of paginated results.

  • What we need to do is a middle where function always takes request response and next.

  • So we need to actually return a function which takes request response and next so we could just return an error function like this.

  • So normally, when you create middle where you wouldn't be able to pass anything to it, you wouldn't be past this post because you're passing a function that accepts request response and next but in our case, were passing post to this paginated results.

  • And we know that the result of this function here needs to be another function that takes request response and next.

  • So down here were making sure we return a function that takes request response and next.

  • So it'll properly work as a middleware.

  • And the way middleware works is that actually executes before all of the code inside of your thing.

  • So we have all this code instead of her app dot get and this middle, where is going to execute before it?

  • And if we call this next function, it'll actually move forward and call the code inside of the next section, which in our case, is this get section for our users.

  • So what we want to do inside of here is just copy almost all of this code.

  • Let's just get all of this code from our users.

  • Copy this down inside of our paginated results.

  • And wherever we have the word user, we want to replace this with our model.

  • So it's that a user's we're gonna do model that link instead of slicing, we want to slice our model.

  • So there we go.

  • Now we actually have a results.

  • Let's make sure we invent this properly so that we have this results variable, but we want to save this so that we can access it inside of our app dot Get so what we can do is we can actually save this to our response.

  • What we can do is we can say rez dot and we can call this whatever we want.

  • I'm gonna call it paginated results.

  • We want to set that equal to our results.

  • This is just this variable right here.

  • And then we want to call the next function just like that.

  • And now we control all of this code instead of here, and all we need to do is send down our paginated results.

  • So we could just say a result that paginated results and all we need to do is make sure that inside of here, that we actually do paginated results and we pass it in the users.

  • So just change this post to users here.

  • We can do the exact same thing in our post up here for paginated results.

  • What?

  • Save that.

  • And now what's queer our users and make sure it works.

  • You can see we query, we get the exact same results are 1st 10 users and we can change this to post hit send requests and you can see when I'll get our post instead and we didn't have to copy any code.

  • All of our code is in this paginated results section down here.

  • And let's just kind of go through a little bit how this works.

  • If you remember, we pass in the model we're using, for example, post or users.

  • And then we're returning a function which acts as a middleware.

  • And as soon as we call next, it's going to go to the next chain of events, which in our case, is this function we defined here, which is returning our Jason for both of these, and we're doing just all the same stuff inside of here we were doing before.

  • The only difference is we're actually setting the paginated results to our result variable so we can use it later on in our chain, as you can see right here.

  • And that's great for setting up the basics of pagination and then extrapolating that into this middle where function here.

  • But what if we actually want to use this inside of a database?

  • Well, to do that, we're gonna set up a very basic mongo D B database using mongoose.

  • So if you don't already have mongo d be installed on your computer.

  • Check out the video link up in the cards or the description, and that'll show you exactly how to download Mongo Devi.

  • And once you're done with that, you can come back to this video.

  • So it's quite out of our server here we did to install a library called Mongoose, and this is just going to allow us to easily interact with Armando de Be database through this kind of rapper.

  • That just makes it so much easier.

  • Now that we have that installed, we can remove a lot of our boilerplate code, what's remove these users and these post variables, and we don't actually this post get anymore.

  • Now the very first thing that you need to do with Mongo, D.

  • B and Mongoose is to set up a schema, which will allow us to actually access Mongo Devi and save records in a collection.

  • So to do that, we're just gonna create a file called users dot Js is going to be our schema so we can import Mongoose into here.

  • We're just going to be called choir looks require.

  • We want to require mongoose just like that and what we're gonna do is set up our user schema so we could just do that here.

  • There's going to be equal to a new mongoose dot schema and the scheme is going to take all of our data, all of our properties for our user.

  • In our case, we just have name because I d is automatically generated.

  • And we're gonna tell this that we want this to be a type of string and that we want to always require our user toe, have a name, starts out very basic user schema.

  • And the last thing is, we want to export that user scheme us so we can use it so we can say module that exports is going to be equal to mongers, clips along views dot model.

  • And we want to make sure that this model here has a name in our case.

  • We're gonna call it User and our schema, which is our user schema.

  • And with that setup, we already have our user model created so we can actually start creating users saving users and, most importantly, querian and paginated our users list.

  • So now back into our server, what's actually cook up our server to our database so we can have in here.

  • Constance Mongoose is going to be equal to require of monkey is just like that.

  • And also, while we're at it, let's import our user so we could just say user is going to be equal to require dot slash users just like bet.

  • So now we have a user model and our database connector and to connect our database.

  • We just want to say mon views, Doc connect.

  • We're gonna pass it the u R l Normally this you're ill.

  • You would want to save in an environment variable, but for the purposes that application here we're just going to write it directly in this connects string.

  • So what we need to do is save mongo D B colon excellence backs last blow co host and then another backslash and the name of the database we're gonna be creating.

  • We're gonna call this pagination.

  • It really doesn't matter what name you use and what's just save that and start up our server to make sure it works again.

  • NPM run death start and hopefully everything is green and we have no heirs.

  • But you'll see.

  • Of course, we haven't air so let's see what that is.

  • It's as required is not defined.

  • And it looks like here I didn't put true for required.

  • I just forgot that property.

  • Now, if we say that and check, you can see again, we're having an heir and it's saying users is not defined.

  • And that's of course, because we don't actually have our users.

  • Variable.

  • We're gonna change this to our user model, and now everything should work properly and we're getting some deprecation warnings, and this is actually okay.

  • What it's pretty much saying is that Mongoose goes back and uses some older versions of Mongo D.

  • B, and we just want to tell it to use the new version.

  • So it's just copy this code and paste in here.

  • We need to use the New Europe are, sir, and we also want to use the unified topology so we can pace that in here also with a value of true.

  • Now, if we save, you can see our deprecation.

  • Warnings have gone away, and depending on when you actually watch this video and implement this, you may have more or less deprecation warnings that you need to worry about.

  • Just copy over the code if you do have them, and it should work just fine.

  • Now, the next thing we need to do is just populates.

  • Um, default data inside of our model the very first time are out, Loads up.

  • Normally, you wouldn't need to do this, but since we have an empty database, we need to add some data to it.

  • So mongers actually gives us a really great tool to connect to the database.

  • We could just say mongoose dot connection, and this is going to be our database.

  • So we could just say const.

  • D B is going to be equal to that.

  • Then we can say d v dot once.

  • So the very first time that we open up our database so we'll say open.

  • We want to run some function just like this, And this is going to be in a sinking dysfunction.

  • So it's just put a sink in here just like that.

  • And inside of here, the very first thing we want to do is check if we have any users.

  • So we're gonna say users docked count documents just like this.

  • This will give us the count of all documents if we execute it, and we want to check to see if that's greater than zero.

  • And since this is a synchronous, we just want to await this just like that.

  • Flips.

  • And now it's saying, If we have any users in our database, all we want to do is return because after here, we're going to actually implement adding our users to the database.

  • So if we have users, we just want to return so we don't add even more users.

  • We don't wanna have duplicate users, and now we're gonna do is going to use promise dot all so we could just execute a bunch of code inside of these promises.

  • We'll just have a simple dot Then at the end, which is just going to log out for us, comes out log added users.

  • So one sided.

  • Here, we're gonna add all of our different users on.

  • We can do this by just saying user dot create, and we just want to pass it in a name, and the name here is gonna be user one just like that.

  • But a comment the end, and we're gonna do this a bunch of times, so we have a bunch of different users.

  • 23456 Same old, same old.

  • 10 11 12 Just like that.

  • And now if we save this, you should see after a little bit of waiting that we should have a screen printed out for us.

  • Counseled out long added users.

  • And as you can see, it's added all the users for us down here.

  • So we know that everything is working for us.

  • And if we save this again, you should see that the added users doesn't show up because it actually returning out here because it mechanize is that we have users.

  • Now, with all of that out of the way, we're finally ready to actually implement the pagination for our database.

  • We have users in the database, and now we can actually do the pagination, and this is going to be very similar to our pagination worked before.

  • We can actually keep all of this code up here at the beginning.

  • Exactly the same.

  • We can keep all this code for starting and index exactly the same thing.

  • Only thing that's gonna change is how we actually query our model.

  • So what we want to do is we want to find users and we want to find all the users.

  • So we're not gonna pass anything inside of our find.

  • And then what we want to do is we wanna limit how many users we have to the limit that we got past in.

  • So this will only return five users if we pass a limit of five.

  • And in order to start at the right section, we just want to make sure we skip and the skip is going to take a number which is going to skip to in our case.

  • We want to skip Tore, start Index and then on Lee get the next.

  • However many we limit units and then we can just run the exact function.

  • And of course, we want to make sure that we await this because this is a synchronous code.

  • We can wrap this inside of a tried catch.

  • So instead of a try here, we just want to put this actual code, and we want to make sure that we call our next inside of the tribe.

  • If that executed successfully.

  • If, for example, we had an air in here, all you want to do is catch that air.

  • We want to send that air to the user.

  • So we want to just come in here and we want to say Rez got status just like that boom instant status of 500 which one?

  • I have a simple Jason message so we can say message is e dot message.

  • And of course, we also want to make sure we set our quest.

  • Our response, paginated results just like this.

  • And we don't need this error here.

  • I don't know what I was thinking about that.

  • Now if we say that you can stay, we have an error with the application.

  • It says it wait is only valid in a sink functions.

  • And of course, we just need to make this in a sink function.

  • Now if we say that everything is green down here, so it's actually try to query our users and see if this works well.

  • We need to do is change this to users here instead of post.

  • So we got users and let's make sure that we query.

  • Let's say a limit of three we want to start at the second page would send that request and you can see we have our previous being shown up with page one, a limit of three a results mean shut up for user's 45 and six.

  • But for some reason, our next is not showing up.

  • We must have some kind of error with our next.

  • So let's go and make sure that we check wire Next is not showing up inside of our server.

  • We go all the way down here.

  • You can see obviously our model that length there is no length to our model.

  • What we need to do instead is actually check the count of our documents.

  • And, of course, execute that and make sure we await that.

  • Now, if we save that, go over here, send this request you can see next is properly showing up.

  • And if we make our limit really large, for example, we make it 14.

  • We said our page toe one.

  • Send a request.

  • You can see that next in previous no longer show because there is no next or previous page to go to.

  • And that is how you do everything from the most simple pagination to the most complex database related pagination.

  • If you enjoyed this video, make sure check on my other videos linked over here and subscribe to the channel for more videos.

  • Just like this.

  • Thank you very much for watching and have a good day.

Hello, everyone.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it