Spring Data JPA Pagination with Angular

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's going on guys this junior here and today i'm going to show you how to build pagination using spring and spring boot and we're going to put it all together by building an entire application back in and front end and i'm going to show you that you not only have to make pagination work in the back end you also have to build the front end which is also as important as the back end and for this we're going to build an entire application so we're going to build the back end with the database connection saving all of the users in the database and then we're going to use spring data jpa to generate the paging of the application and then we're going to use angular on the front end and i'm going to show you how we're going to put this application together so this is the final result that you're looking at right now and i'm going to give you a quick demo just to show you how this application works so i'm going to refresh the page so when you first come into the application it's gonna load all the users and it's telling you that you have 10 pages worth of users and it's going to display 10 users per page and i'm going to show you how you can change that if you want more users and also show you how to allow the user to change this so that they can ask how many users they want to have per page but for this demo i'm just using 10 so we're going to show 10 users so at the top i have the navigation bar and we have a search box so that we can search users and i'm gonna get back to the search backs in a minute so we can search users by passing in their name here and hit the search button and once we do this we should only see users whose name contains the character that we put in the search box but like i said we're gonna get back to this in a second so the first thing you notice is at the bottom i have the pagination so this is the actual pagination as you can see here and because we're on the first page then the previous button is disabled and this is what i meant when i said that you also have to work on the front end because the front end is also very important so if you build the back end and the packaging is working in the back end now what about the front end because you need to build all of this functionality and now i can go to page two so if i click two it's gonna take me to page two now i put in the database 100 users i destroy the database after i build the application and then i put in all the users again so that the user is going to be ordered from id 1 to id 100 so now you see we're looking at users of id 11 to id20 so we get the next 10 users and i made it this way so that it can be easy for you so that you can see we're getting 10 users so if i click again on page 3 then we're going to get user from 21 to 30 and that's what we're looking at here and also of course i can use the next button so if i click next then it's going to take me to the fourth page where i have users from id 31 to 40. and that's true if i keep pressing next i can also go backwards and you notice now because we're not on page one then we can go backwards so i click previous then i'm back to page 4 where i get users from id 31 to 40. and if i go back all the way to page 1 you can see automatically that the previous button is disabled because if i'm on page 1 then i can't go further back and also the same logic applies for the last page so if i click on next you can see i'm going through all the different pages and once we get to page 10 the next button is going to disable so if i do 9 and then add the last page 10 you can see the same functionalities because i'm at the end of my list i don't have any more users we don't want the users to be able to go to next page if they're on the last page that wouldn't make sense and this is all in the back end so this is not built on the front end this is building the back end so every time we click a page then we make a request to the backend to request that specific page for that information so that's the basic pagination so now let's say i want to search some users so for example if i go in here let's say i'm going to search for mary i don't know if i have any merit but i'm going to search for mary so i'm going to say mary search i have no users by that name and you can see no users found so we don't have our table anymore we just have an empty list and then i'm showing the users like you the person using the application that there's no users to display so now i can go and delete this mary and search again because i don't put in any search term in the search box then it searches everybody and this is the behavior that you would expect from your application now say i'm going to search for users with a n and their name okay so if i put a in here and click search you can see now i have three pages and this is really important because pagination is still working with the search so when i put the search term in there in this case a n and you can see all the users that i have here they have a n in their name so you can see a n here constantine there's a n here there is wendy's a and francis a n so all these users at some point in their name there is a n the characters a and n together in their name and like i just mentioned pagination is still working with the search so now i can go to the next page and you see i still have more users with a n in their name if you pay attention to the names and also everything else is still working so if i'm on the first page in the search result then the previous button is disabled i go to the next page go to the third page i have two users in the last page so cindy and tamie lynn fear you see they have a n in their name and this is the last page and the next button is disabled so even when we search a term or we search the name of the users the pagination is still working as expected and that's what you want in the application and why i mentioned it's important to build the back end but also the front end is really important you're actually going to be writing more code and the front end to make this functionality work than the back end so i can go back to the first page i can go up here i can delete this and then search again and now i have all my users displayed so this is the functionality that i'm going to show you how to build using spring boot and the backend with spring data jpa and angular in the front end now if you don't use angular let's say you use react.js or some other library most of the logic that i'm going to write here it's going to be the same you're just going to have to change the syntax to accommodate for that specific javascript library so even if you're not using angular this is still going to be really useful for you because you'll get the general concept and ideas about how to do this and this is the way that applications are supposed to be built because we never want to load a thousand users in a ui page because it makes no sense and the person using the app won't have a good user experience because it's too many users they can't really manage it which is why imagination is really important and also for performance because you never want to load let's say a million users you just do like a select all from user stable and let's say you have 10 000 users you never want to load 10 000 users anytime so whoever is using your application they never want to see a thousand users displayed on the screen even though you see there's a lot of tutorials out there they're just doing select star or still like everything's every row in the table this is never done in practice because it's not good for performance you never want to query the database for every single row to be returned unless you're absolutely certain that you're never going to have more than let's say 100 or a couple hundred records and even though you have a couple hundred records you never want to load like 200 users on a ui page it's just it's just not a good user experience so pagination is really important and that's what i'm going to be teaching you today so i hope you're excited and let's get right into it usually when i build applications like this like when i build the back end and the front end i usually start with the back end and then move on to the front end but this time i'm going to show you that you can actually start with the front end and then move to the back end so what i want to do is to build the ui so the first thing i want to do is to put together the ui now if you're familiar with bootstrap you already saw that i was using bootstrap and i like to use bootstrap because their classes are really convenient so it doesn't take much for your application to look good i'm going to search for bootstrap and press enter and i'm just going to click on the first link here and go to the docs and come down here i'm going to just copy [Music] see i'm going to copy this right here okay so this is just a very simple index file that you can start with and it has the import for the css so you can see they have the import for the css and the import for the javascript at the bottom i don't think we're going to use the javascript but i'm just going to edit anyway so i'm going to copy this and then i'm going to open visual studio code so i want to be really transparent with the ui i'm going to show you exactly that i'm not doing anything really fancy and go line by line and the code with you so that you can see how i built this app so i'm going to copy this and then i'm going to open visual studio code i'm gonna bring it over so this is visual studio code you can see here blank empty i have no folders no nothing and i'm gonna click on new file and i'm just gonna say it's gonna be like a text file and this is the file right and i'm gonna paste this in there so whatever we just copied i'm just going to paste it in there and now we can save this file because it's not saved yet you can see it says untitled there's no name for the file so i'm going to do ctrl s or you can do file save it's the same thing ctrl s and it's going to ask me to save the file so i'm just going to choose a location i'm just going to put it in my document and here i'm just going to give it a name at the bottom so i'm going to call it index.html it should already be html as you can see here the operating system detect that it was an html file and i'm gonna save so this is our index.html file i can open this file in the browser so that you can see what it looks like and then work with it so let's go back to chrome and i'm gonna need this so we're not gonna close it yet let's go to my document and i wanna do index.html so index.html and this is our app for now so hello world we have the application already gone so the first thing we need if you remember we had a navigation bar so i'm gonna click on the search here and then search for navbar so i'm gonna say nav bar okay and then i'm just gonna click on it and uh scroll down a little i think the one that i'm using is that first one so the first navbar example from bootstrap we can just copy this and paste it i'm going to copy this right here and then go back to visual studio code and inside of the body instead of hello world i'm just going to go ahead and paste this in there okay so i paste it in there you can see all the code is in there and now if we go back and refresh we have the navigation it doesn't have the right colors yet so i'm going to go ahead and fix that right now so let's go back to visual studio code i want the background to be dark so i'm going to change the light to dark so i'm going to say dark and i want everything else to be a navbar navbar i think we have to do navbar dark okay because i like the dark color better and if we go back now and refresh now it looks more pronounced you can see it better so another thing i want to do is to not have the menu like the actual menu and the nav bar stretch all the way across to the end of the screen i want it to be like somewhere here using the container so let's go back to visual studio code and the only thing we have to do really is to just change this from container fluid to container i'm just gonna remove this delete it go back refresh you see everything is aligned the button also needs to be more pronounced i want the button to be just green and not have a green outline i just want the whole button to be green let's go back to visual studio code and uh we have the button outline success all i have to do is just remove the outline and also while i'm here i'm just gonna remove um some of the stuff in this navigation so i'm gonna keep home in the navigation so that's the home li and i'm going to remove everything else because i don't really need all these other stuff so this disable all this can go delayed and i'm going to clean up a little right here so now if you go back and refresh okay so that looks much better looks more like what we had in the demo so the next thing now we need to have is a table so we need to add the table where we're gonna display all the users so back to bootstrap and we're gonna search for table and we're going to click on the first link and so this this table should be fine we can make it look nicer later but you can just click on the first one and then we can add classes as as we need so let's go back to visual studio code so right after the nav bar which ends on line 30 28 so we can collapse this for now and go down here so what i want to do is to put everything inside of the container so i'm going to do that container and that's going to create a div with the clasp container because i want things to be still inside of a container because the navbar items are in the container so i want everything to be aligned and then because we're using bootstrap of course we need the row and inside the row i want everything to be in a column medium 12 and inside in there is where i'm gonna paste the code so i'm gonna do ctrl v we're gonna put the table in there so now if we go back and refresh okay so you see the table is still inside of a container because we want everything to be aligned so now i have to put the uh users list at the top here and push this down a little because right now it's too close to the nav bar so let's go back to visual studio code and i'm gonna expand the navigation again and inside of the form you can see the form here the little form we have at the top i'm gonna put search users for the placeholder okay so that's the only change that i'm gonna do in the form for now and i'm gonna collapse this back now inside of this container which is where we have our table you can see the table starts here on line 32 inside of the 12 column that i want to see on medium screen i'm gonna put mt for margin tap and then i'm gonna give it the value of three so this is a bootstrap class that you can use now just to give a little bit of margin at the top and you can also use mb for margin on bottom so margin tab three that's going to push it down a little bit and then after that i want uh let's say an h3 so i'm gonna do h3 and here we're gonna put user list okay you can put whatever you want but i'm just going to put users list and now if i refresh so we get user list and then we have the table and then we have the nav bar now if we go back to bootstrap and look at the table i want the table to be table stripe you can see every other row is a different color and that's achieved by using this class here so i'm gonna just copy this class go back to visual studio code at the table here where we have the table class i'm gonna put a space here and then paste that in there and go back back to our app refresh you can see i have the same effect now the next thing that we have left is the pagination so the pagination that we're gonna have here at the bottom so let's go back to bootstrap and in here we're gonna search for page nation and click the first link here and this is good for us you can see this is really simple just regular html elements and stuff and then the bootstrap classes on it so nothing fancy nothing crazy so i'm gonna go ahead and copy this and then open visual studio code back and at the bottom after the table so here's the end of the table at the bottom here i'm gonna put a space and paste that in there so you see i just paste the same code that i just copied let's go back to take a look at this and refresh okay so it's on the left which is okay we can move it on the right but i'm just letting you know that if it's on the left it's also okay i just like it on the right it looks better in my opinion but you can keep it on the left if you want that's not a problem so let's go ahead and move all of this to the right because i like it on the right let's open visual studio code and the way we can achieve this is by going inside of the ul so the unordered list we can put another bootstrap class which is called justify uh justify oops gonna move the cursor away so justify dash content and we want this to be end so that's the end and if we go back now refresh you can see now it's on the right now the other thing that i have is the little the little i guess arrows there's a name for them which i don't know but they're arrows pointing to the left and the ones pointing to the right which you see here if i scroll down you can see then the second example that's what they're using so instead of the words previous and next they have this little icon here and we can achieve this by just passing in this so i can just copy this go back to visual studio code so after we have next so we're gonna have both so we're gonna have next and then we're gonna have this is the end one so i'm to paste this in there and for the previous one this is the same so let's go back um so that's the one for next so when we're going forward so the one we're going backward is different so i'm gonna copy this as well um actually i need to it's not in the right place so let's just copy this entire li and go back delete this i'm just gonna do ctrl z and i'm gonna just paste this in there just so that we don't have to type everything out so this is how it's supposed to be like and then here we're gonna say next okay so that it can be easier for us less typing uh also gonna remove that one li and just copy this li and go back and then paste it here instead that's the first li in the unordered list and then here we're gonna say previews previous okay and save and go back refresh okay so that looks better so we have previous next with the little icons all of our pages are gonna be in between these two so you saw everything about the ui for now we're gonna get back to the ui but for now this is everything that we have so all the ui is built in front of you nothing really crazy i just go in bootstrap copy things and then just paste them in there so that's what we need for the application so we have everything we need now what we're going to be doing is we're going to start working on the back end and make sure that we get pagination working in the backend so at this point the ui is ready there's nothing else we have to do here everything else is going to be dynamically generated so we don't have to do anything else here we'll add you know a few more things here and there in the ui but we need to have the actual angular application running so that we can put in this logic but for now it looks exactly the way that it should look so there's nothing else that we have to do here for now so i'm going to start working on the back end and i'm going to go here i don't think we're going to use bootstrap anymore and i want to go to spring initializer uh i can never spell that right i actually did so we're going to create a maven project and it's going to be a java project and version 2.71 is fine with me for spring boot and then i'm just gonna go ahead and fill out this information so i'm gonna put here and the name is going to be pagination um yeah everything else looks good i think i have java 18 so i'm going to choose 18. i just upgraded to 18 i think a couple days ago and now i have to add the dependencies so we're going to be building a web application or a web server so we need the web we need the mysql connector so my sql connector it's going to allow us to connect to the mysql server instance that i have running on my computer and we need a data jpa so jp a and we need the lumbar so that we don't have to write all the getters and sitters so the web dependency the driver for mysql spanning data gpa and lombok and i'm gonna go ahead and click on generate and it's gonna create a zip file so i'm gonna go on my computer i'm gonna unzip this file and then i'm gonna open it and intellij so feel free to do the same thing i'm gonna go ahead and do that and then i'm gonna be back with the application open and intellij so that we can start working on it so i have the application open in intellij and let's open up everything here just to make sure we're good so we have the main application class so this is the main application class and we can run it now but it's gonna fail because we don't have any database connection in the properties file and while i'm here i'm gonna go ahead and refactor this give it a different name i mean i don't like properties file so i'm going to change it to yemo so application.yemo we're going to be putting some configuration here for our connection to the database in just a minute so what i want to do is to create the different packages that i'm going to need for this application so i'm gonna go inside of the main package here right click go to new create a package and this is gonna be the domain and i'm gonna create another one this is going to be the repository so repository and then we need the resource so let's do new package resource and also we need the service so new package service and inside the service i'm going to create the implementation folder while i'm here servlet no right click new package and employment so the service implementation they're gonna go inside of this folder and i think that's all we need for now so the first thing is we're gonna start with our domain so i'm gonna create a new class which is gonna be the users that we're going to be managing so that's going to be this and we're going to put in some properties on these users and let's collapse this from a room so what we need is an id so we're going to say private long we have an id we need a we need a name so we're going to say private string name and private string we need an email we're just filling in some data so that we have something to work with let's give him a status and i'm also also going to give him oops private string let's do address and we can give him a phone so private string phone and we can give him an image i just pick a few things i think will make the ui look better so image rel so we give them a few things so this is supposed to be string okay so this is the user again we're gonna let jpa take care of this entity for us so we need to add some annotation so the first one is going to be add entity and we want the new artist constructor so no that no arcs constructor from lombok we need the all arcs instructors so add oh there it is and i also want the super builder so i'm going to add super builder oops super builder and then i'm going to do control shift um so it's going to be ctrl command o and it's going to remove any uh import that i'm not using and i also want getters and setters so i'm going to say add getter and add setter so we have setters and getters we have entity for this for gpa to manage and then we have the all arcs constructor and then we have no arcs constructor here and i want one last property that's the json include and i want this to be non-default so none on the let's see that's the second one so what this is going to do is if the default value of any of these properties is what's being returned then it's just not going to put it in the json object you're just going to remove it all together so that's what this is doing so now we're getting an error because we need to put the add id on this so we're going to say id and also we need the generated value so at generated value and we want to set this to let's say identity it's gonna be that one okay so you can do a static import for these because it looks nicer when they're aesthetically imported um i'm gonna clean this up and do the same thing for the include as you can see here um put this down a little come up here and at the static import for this okay and then i'm gonna do control command o just to clean and arrange the import now this is looking good so this is the user class that we're gonna be managing or working with and we're gonna page this so that's why we're creating this class here you can change this to whatever you want i'm just using user as an example so now we can create another one which is going to be the http response so i'm going to call this http response and this is going to have a few properties so i'm going to say protected let's do a string and i'm going to call this time step oops it's time step and we want another protected that's going to be an integer and this is going to be the status code so the 200 400 etc and another protected and that's going to be of type http status coming from spring and that's going to be the status and then i need the message so if i send a message to the front end which is going to be represented as a string and then lastly i want the data so here i'm going to pass in the map and i want the map to be of anything so i'm going to put a question mark another question mark and then i'm going to call this data so the data is going to be inside of a map so that we can pass as many pieces of information to the front end as we want that's why i define the data i like this and every time i'm building an api i like to make all my responses uh uniform so that's why i'm creating this response so every time i'm sending something to the front end it's going to have that format so that i can map it better in the front end as well so keeping everything uniform and clean but you don't have to do this you can you know send an array of users back to the front end my array of users is going to be inside of a map because i like to work with it better that way and then i want to add it data on this from lombok and also super builder so we're gonna say super builder and lastly i want the same thing so let's copy the this right here and then paste it here because if something has the default value then we don't want to return it so for example if this time step is null then it's not going to be included in the json when this is pushed forward to the front end as a json so i think this is everything that we're going to need in terms of our domains we're going to have the user that we're going to be working with and then we're going to have the hdb response next thing we're going to do is to add the repository for this user class or entity i'm gonna go into the repository here right click on it and go to new java class and this is gonna be the user repository enter and we're going to extend the paging and sorting repository so you have to be very careful here so now we're not just extending jp repository but the paging and sorting repository which is still jp repository but in addition to the stuff that you get with jpa you also get some sorting and paging functionalities as well so it's really just the same thing and here again we're gonna do the typical stuff pass in the type we want to manage here which is going to be the user and then we want to let's go ahead and import this will quick from our domain and then we're going to pass in the type of the primary key here which is long so if i go inside of the user again you see the type of the primary key is long so this is all we have to do for now we just have to define one method so i'm going to go down here and this map is going to return a page it's going to return a page of user and i'm going to say find uh let me put a space here so find by name containing okay so this is how you define these names for these um methods and then here i'm going to pass in the name okay so the name has to exist inside of the user class and then i'm gonna pass in pageable to make sure that this can be paged so we can pass in a page information in here if we want and this is why we're extending the paging and sorting repository because it's gonna allow us to pass in the page and paginate the response and this is not supposed to be a class it's supposed to be an interface so that's why it's giving us all these errors i'm going to collapse these so yeah that's all we have to do so we're extending still gpu repository but another one called paging and sorting repository that's going to allow us to page and sort things easier and that's all we have to do here of course we can add more methods here but for what i'm trying to teach you this is going to be the method that we're going to use to uh sort and page things well we're not going to be sorting but you can also sort by passing in the direction of the sort and the pageable object here but we won't be focusing on sorting we'll be focusing on paging so this is our repository so now what we have to do is to create a service and then make the service use this repository we're gonna use this method and our user service so that we can pass that service to a controller where we're gonna make the request so i'm gonna go into the service folder or package create a new class and i'm gonna call it user service press enter and this is going to be an interface i keep forgetting to choose interface and in here we're going to say we want to return a page of user so it's going to be a page of user and let's just call it get users and we're gonna pass in the optional name so they can possibly pass us a name or they should pass us a name in this case and then they can pass us the page that they want to see and they can also pass us the size of the page so the size of the page is going to be how many elements that we want in that page and the end page is which page like page one page two page three and the name is the name of the user that they're trying to look for which is why we named this find by name containing so this name is important you have to name it that way like find by id like find by name this is how gpa is going to interpret this to create the query to query the database for you and optionally you can come in here and pass the at repository on top of this class it's not really required but if you want to have it on here you can so let's close this for now and close the user close the response so this is a service all right we're just gonna have one method in there that's gonna just call the method from the repository so this is what we're gonna inject inside of our controller and you're gonna see that in a minute and what i'm gonna do now is to just go and create the implementation so create a new class and this is going to be the user service impl and that's going to be a class and this is supposed to be let's go ahead and rename this rename so this is just the service refactor okay so you can see the services here and then we're gonna create another package instead of the service called implementation and we're gonna move the implementation in there factor okay so that's a better structure so the user service is here inside of the service package and the implementation is inside of the service implementation package as you can see here so and here first thing we have to do we need to do some dependency injection so i'm gonna pass in the annotation at service um also we can do transactional but we're not gonna need it because we only have one method in there and then we have to do required args constructor and also um i need to log some stuff so we're going to do slf 4j okay so this is going to allow us to log some things as requests are coming in so in here all we have to do is to provide the repository so here we're going to say user user repository give it a type reserve repository so we have injected the user repository in here and then now we have to implement the user service we're going to say user service and we have to implement that one method implement click ok all right so we already have the repository here all we have to do is to call the repository and then call our method so find by name containing and then we're gonna pass in the name and then we need to pass in the page so we can pass in the page requests of and then you can see here we have different methods that we can call so there's one where we can pass in the page and the size there's one where we can pass in the page and the size and the sort and so you can also sort and you can tell in which direction to sort or which properties to use to sort but we're not going to be sorting i mean i don't always find sorting really useful for the applications that i've been building but paging definitely really useful so here we just have to pass in the page and the size because we're getting them from the request or from the method that's going to call this method so whoever is going to call this method they have to pass in the name and the page and the size and we're going to pass it into the request and here we can do a static import in this and i'm going to do ctrl command o to clean up the imports and then before we forget we can use the log so we're gonna see log that info oops info and we can say uh fetching users for page whatever the pages of size whatever the size is and then we're going to pass in those values so that's going to be page size just so that we can see some logs in the console so fetching users for page that's supposed to be four four page whatever the pages of size whatever the size is so that's all we have to do here for the service implementation and this is gonna do all the paging for us we're gonna give it what page we want the size of the page if we have a name we're gonna give it if we don't have a name we're gonna pass empty string here and it's just gonna query the entire database so that's all we have to do for the user service implementation let's go ahead and work on the controller now so inside of the collapse these so instead of the resource since this is a rest api i'm going to create a new class and i'm going to call it user resource enter and we need to add some annotation on here so the first one is going to be rest controller so rest controller so that we can make this a rest resource and we can add in the request mapping here so request mapping uh we're gonna say we want this to go to forward slash you can put like you know v1 for slash or v2 uh api blah blah blah but that's that's up to you and then um we need another one which is the required arcs constructor so required rx constructor okay so because we're gonna inject the service in here and then at the top of the class we're gonna do private final user service which has only one implementation so we're gonna inject it in this class so we're gonna have one method in there so we're gonna say public and that's gonna return a response entity so we're going to say response entity coming from spring framework and we want to return the http response so here we're going to see http response that's coming from our domain and let me collapse these okay and we're just going to call this get users and here we have to pass in a few things so the first thing is going to be the name so we're going to say requests param i'm going to show you a trick we're going to do here so i'm going to make this an optional of string so instead of just a string i'm going to make it an optional of string so i'm going to say it's an abstract string and we want to call this the name and we're going to do the same thing for the let's copy all this we're gonna do the same for the page and we're gonna do the same for the uh size i'm gonna put these on the new line so you can see them better new line so this is going to be on integer so we're going to say integer oops integer and that's going to be the page so name this page and also this is going to be an integer oops copy paste and this is going to be the size okay so this is all the request parameters that we're going to be expecting from the user and we can just return and a new response entity of okay and inside we're gonna pass in the body here so we're gonna say body which is of any type inside of the body is what we're gonna call the hd response so we're going to call the builder and then we're going to pass in our information so the first one is the timestamp what we can do is to call now and we can call to string on it so to string so now uh let's see if i can import this more action import static uh that's the one that we want let me check make sure this is correct so java logo did time so we want the local date time that's the one that we want so look at the time now okay and then we can call to string on it and give us the the time step as a string and then we can pass in our data so the data i'm going to give it a name which is going to be a page so that's the key inside of the map and then the value is going to be the user service that get users and then we're going to pass in the name the page and the size now if we get null this might throw us an error i didn't test it but i'm pretty sure if we said no it might throw an error i didn't test so to avoid this which is why i'm using the optional we're gonna do or else so that we can supply something else so if they don't pass in the name we're gonna pass an empty string and we're gonna do the same for the page so or else so if they don't pass us a page then the default page is zero and we're gonna do the same for the size we're gonna say passing the size if there is one or else i'm gonna start with 10. okay so that's why using an optional is really important here because we can pass in default values if these values don't exist and then after that we can pass in our message so i'm going to say message and here we can say something like users retrieve or something so retrieved and we can pass in the uh status so status i'm gonna pass in okay okay so that's coming from spring framework uh do aesthetic import on that and then we're gonna pass in the status code so status code we're gonna pass in the okay that value and lastly we have to call the build okay this is how we're gonna create the object here and we're getting an error here because this is supposed to be a map so i'm going to pass in a map that of and then open and close so all this is supposed to be inside of the map and we can do a static import for this as well all right so now all we have to do is to annotate this method so here i'm going to say add this is going to be a get mapping and we want to make this go to forward slash users for example so users okay so that's all we have to do for the controller we're only gonna have one method in there that's gonna retrieve all of the um users per page so we're gonna pass in a name or empty page or zero or page the size or 10 because we want to get 10 users if they don't pass in any any size and that's pretty much everything we have to do for the user resource the next thing we have to do is to put the configuration for the database so that when we run the application to test it it doesn't fail so let's go ahead and do that i'm gonna go inside of the application.properties file or em file in this case and i'm just gonna go ahead and paste the configuration so i'm pretty sure you guys are very familiar with this configuration already i'm changing the port to 8085 and then i'm setting the url for the database um you can see here i have a local ip address that's because i have a computer like a tower that i use for experiments when i'm doing stuff and i don't want to do them on my computer so on that computer i have docker running and i have an instance of my sql so that's why i'm using this ip address of that computer but in your case most likely it's going to be localhost so don't worry too much about this it's just another computer that i have running on my network and then password username and some other configuration for a hibernate and stuff so this is really not anything complicated that's something you probably have seen before so i'm not going to spend too much time on this but we're just passing in the database information so if i close this and go ahead and run the application hopefully everything works so let's run it okay it looks like it's building itself okay let's see what happens okay looks like it ran fine we didn't get any errors or anything and i think i set this to update so the ddl update will not crash my database because i manually put data inside of the database and i'm going to show you how i did this so application is running we can go ahead and test it we're going to do that in a second so i want to show you this macaroon website and that's what i use to generate the information that i want for the users to insert inside of the database so instead of you know go to the application class and then use the repository to insert users i just used this tool here and then i generated 100 users so for example if i do this and i say i want sql and then i'm going to call this user for example what i did is i just click on preview and then it gives me all the sql queries and some dummy data and you can choose for example like let's say i wanted this to be the image underscore url and then here i can choose for example image and then you can see it says dummy image url so then when i do preview then we get a bunch of dummy images in here so this is how i generated all this data and i'm going to show you that i'm going to bring up my scale workbench so i generated this user.sql i just put that first line so that we can use our database so using the pagination database and then here's all the statement so all of this is gonna go inside of the database and that's a hundred of them you can see we have a hundred lines of code here and then the other thing i did is you see that i'm using this dummy image and i didn't like this so what i did is in here i was doing some experiment i just changed some of the statuses of the users and then i changed the image url of the users as well so i just used the random user api i can copy this and show you that as well and then i created a random number from 0 to 100 and then that jpga because that's how these api generate images so if i go back now and paste that in there and go to user photos and i can pick anyone here let's pick this guy and copy it and if i paste it in here you see it's uh it's men and then a number i've seen that the number is between maybe 100 which is why i do the concat in mysql so i'll show you that right now so i put the beginning of the string some random number between 0 to 100 and then that jpg which will give us a string similar to this and this is how i was able to change all of the user images to use real images and i did the sql safe update i disable it because when you're updating stuff you need to pass in a condition and i was not passing any condition you can see i'm setting the image url to a new image i don't use the where clause to pass any condition and if you don't do that mysql is gonna complain so i just disable this so that i can update all the features so now we have data in our database and i can show you that uh let's open this panel so here's the the table and if i select everything bring it up a little you can see we have a hundred users in here okay so we have enough data that we can use to just test this out so i'm gonna close all this uh donate this don't need this uh let's open postman so we're gonna send a request to um that's gonna be localhost i'm gonna select that first one change this to 8085 and we want to go to users so if i go to users we should get the first page and we should get 10 users in that page because we didn't pass any request parameters so if i send the quest you can see we get the response and we have 10 users so 9 10 id 10 and then if i move this up a little more you can see the page information so we see the total elements is how many we have in total in the table so that's 100 total pages we have 10 pages and then the size of this specific request is 10 because we're requesting 10 and then we have a bunch of other things about sorting if this is the first element or not so all the other information about the page that we're not really using right now so now we can test to pass in some stuff so if i put a question mark and i put name equal and which is something that i know exists so we should have at least three pages so if i send this request you see now i get the first user then the third then the eighth user then the 11th user 18th user so i know that the sorting is working because all these users have a n in their name and then i can say give me so this is going to give us 10 okay so 1 2 3 4 5 6 7 8 9 10 by default it's 10 because we pass in the size of 10. so we can do here we can say we put a end sign and then we say size equal say 3 okay so now instead of giving us 10 it's going to give us three because we're passing in the size here we can send requests again so now we have one then a three and an eight so we have three here so by default it's giving us page zero and how do i know this it's right here and the page information page number zero because that's the default we set in the backend if i want the second page i can put another end and i say page and i say equal page one because it starts at zero so page one now if i send the request it's gonna give me three again but the next three so 11 18 21 and then there's no more and then it tells me that the page size is three so three element in the size and then the page number is one so i can say i have eight pages so i can go up to h page seven so i can come here and say during the last page it starts at zero so that's why i have seven and not eight send the request you can see we have one user in the last page and we have is it the first page no is it sorted no so we have a bunch of information here number seven size three total element is 22. so you see that we have all the information that we need to sort the information and page it and the size it the way that we want i can go back and say give me page six now send the request that's gonna give me the three before that guy and then the rest of the paging information and i can copy this go back to the browser since it's a get request we can use the browser paste that in there and zoom in a little so i'm not using my account you can see here i'm browsing as a guess that's why this doesn't look really cool because i have extension when i'm using my account so i'm gonna go ahead and uh bring another session just so i can show you this so i'm gonna bring it over here and this is what it will look like so i'm using my account now i have this alien as my picture so you can see now i just pasted in the same request you can see now we have all the information in a nice area but it's the same information so pagination is working and the search is working and this is really everything that we have to do for the backend and it's really not a lot of code but as long as you know what you're doing then it should be pretty easy for you to set up the back end using the paging and sorting repository that is provided by spring so that's pretty much everything that we have to do for the back end application is running fine all the logs are coming through so everything is good i'm just gonna keep this running and then what we're gonna be doing next is to work on the front end now you see that because i'm using the pageable we have all of the information that we need to manipulate the ui or the front end to send requests with different page and different size and if we're searching we pass in a name we should be able to build this ui but it can be a little tricky and i'm gonna walk you through everything line by line so let's go ahead and start working on the front end i'm gonna go ahead and create the angular application for now and i'm gonna keep the back and running and then i'm gonna bring visual studio up and i'm gonna open the terminal and see if we can generate the angular application so i'm going to navigate to my documents that's where i'm going to keep the application and then i want to do i need to do cls here and let's do ng new so that we can generate the angular application and i'm going to call it pagination app okay so the backend is called pagination so i'm just going to call the front-end pagination app i'm going to press enter and this is going to take some time because it has to install a bunch of dependencies i'm going to just say yes to this question and be cool with css and just gonna let this finish and then once all the dependencies have been installed and everything then i'm gonna go ahead and open the application with visual studio code okay everything has been installed i'm gonna go ahead and do cls and do code dot and also do ng serve so that i can serve the application well actually i need to navigate inside of this pagination app folder and then here is where i'm going to say code dot and ng serve so it's going to open a new um visual studio code well i guess i don't need to do that uh let's go ahead and just stop this so i'm gonna say control c here just gonna say no ctrl c i'm just gonna delete these and open the other window that i had make it full screen okay so this is the app and we're gonna run it inside of the same terminal so here i'm just gonna save and just serve okay so we're not gonna worry too much about this i'm just going to let it run make sure it's successful and then i'm going to close the terminal panel here so let's just give it a few moments okay so everything is working we can check it on localhost 4200 we're going to do that in just a second but i'm just going to close this for now so this is a brand new angular application and the first thing that i want to do is to put the ui code that we created in the beginning of the course so we're going to put the html file in there so that when we go to the browser we can see the html that we created the index file that we created so let's go ahead and do that so this is the index file i have it open in the browser i also have it open in visual studio code so i have it open here and we're just going to copy everything over so the first thing that i want to do is to copy the bootstrap import to the css import i'm just going to go ahead and copy that and i'm just going to go to the source app and we want to go to the appcomponent.html because this is the main ui page of the application and then i'm going to select everything here except the router outlet we can remove the router outlet because we're not using any routing and just make sure that i clean this and we're going to go inside of the index and we're going to import that right here so i'm going to go down there and import this and back to the index file we also have to import the which we're not really using but i'm just showing you in case you want to set up your application with bootstrap in that specific way because there are many different ways you can import bootstrap in your application back in this index.html file we're going to go at the bottom right after uproot which is where all the elements are going to be put in dynamically and then we're going to paste that in there okay so that looks good and i'm just going to fix this as well i'm going to name it imagination app with uppercase so at this point we should have bootstrap in our application because we have the imports so i'm going to close that now we need to pass in the actual um content here so i'm going to scroll up and inside of the body is everything that we need remember the index.html already has the document format so it has the duct type html and everything so everything we're going to be working with is going to be inside of the battery so we can copy everything inside of the body here uh well actually i don't need this just copy this so we don't need the body we don't need the script why because inside of this in the html we already have the body so we're just working inside of this uproot here which is going to be loaded dynamically so i hope that makes sense now we're going to go inside of the app component.html at the top we can put all of this code okay like i said we can remove the router outlet because we don't have any router but just it doesn't bother me here so with all these changes if we go into the browser now uh remember the app has to be running so if i do control backtick we can see that the app is running on 4200 if i scroll up a little you can see it right here so i can just copy this link and then go back to the browser open a new tab and paste it in there and go there you can see it looks exactly the same so now we have our angular application with the ui the way that we want it to be so this is what we created this is the static index file this is the angular file we're going to work with for the application and then set up variables and all kinds of fancy stuff okay so i don't need this anymore so i'm going to go ahead and close this now we're going to be working on this application and put in all the functionalities so let's go back to visual studio code and the first thing we need to do is to create a service and we need the service to make html requests now we don't need to create a service for that it's just the way that the framework is set up usually whenever you need to make some http requests you want to have a dedicated service to do that for you and keeping with the good practice or the way that the designer of angular wanted a framework to be used then we're just gonna go ahead and create a survey so that we can make http requests to the back and api that we created but you don't have to do that you can put all your logic to the request inside of the app component here we're just not gonna do that so the first thing i'm gonna do is to do ctrl c here and then do cls to clear the screen and then i'm gonna do ng for the angular cli generate and then i want a service we're gonna call it user service i usually like to put services inside of a folder again you don't have to do that if you want to put it in a folder you just pass in the folder name and then the forward slash and then the name of the service in this case it's going to be user and what the angular cli is going to do is it's going to put the rest of the name for you so that's gonna be user service dot cs all the files that it's gonna create now i also don't want the test file because we're not testing here so i'm gonna pass this flag skip test so skip test so we're skipping all the tests so we don't want the test file and then we're generating the service so i'm going to press enter on that okay so you see that it created this file called user.service.ts and it's inside of this service folder so i'm gonna undo the up arrow key twice uh maybe more than twice and then run the application again so ngserv and then i'm gonna do control backtick just to hide the open terminal so now we can go inside of the service and here and the first thing we need to do we need to import the http client so i'm going to say private http that's the name of it and it's of type http client um this is not being imported so let's do import and this is the http client so it's supposed to come from angular common slash http so this is where the package leaves so that's what we want and then the other thing i have to do before you can use the http client you have to import the hdb client module so that you tell the entire angular app that you're going to be using the hiv client and to do this you do that in the app module which is the main module that we have so i'm going to go in here put another comma and then add another import you can see we're already importing the browser module in the app routing module so now we need the http client mandrel you can see it coming up here now we have the http client module we can use the http client inside of the service so i'm going to go ahead and close the app module because we don't need to be in there anymore and then i'm going to collapse the file explorer or the panel here by just clicking here or just do control d i believe so that should close that so now we need to create a method that's gonna call the backend and then retrieve the page of data so this is all we have to do so i can put a comment here i can say make call to the back end api to retrieve page of users okay so that's all we're going to be doing here then i'm going to put this and the comment so that's all we have to do so now i can go down here and then i can do get users which is going to be the function remember this is going to take a name oops um that's the java syntax so we want a name past the belief right and then if they don't pass a name then we're going to set the default to empty string so the same thing that we were doing in the back end so they can pass in a name if they don't pass in a name then we're going to keep empty string and then the page which is going to be a number so the page number like page one page two page three we can set that as a default for uh zero so if they don't pass a page then default is gonna be zero and of course the third argument is the size which is gonna be a number and of course we're gonna give it a default of 10 because we're loading 10 users by default so now what we have to do we can say this is going to return an observable of any for now because we don't have anything defined for the page so this is going to be any and then in here we're going to have the body of the function and we do return this.http.get because we're making a get request the get request is also generic as you can see here it takes a type we're gonna pass in any for now uh we're not gonna keep any i'm just gonna do that for now just so we can see something in action we can pass in the apis i can say for example i'm gonna put backtick and then dial sign open and close curly braces and i'm gonna say this that api url or server url and we want to go to forward slash users so we're gonna go to four slash users now remember we have to pass in the query parameters so we put a question mark and then i'm gonna put another dollar sign open and close curly braces but before that we have to pass in the key so the key is gonna be name equal and then we pass in the name here so we're gonna say name and we're going to do that for the page so we're going to put a hint sign and then we're going to say page equal dial sign open and close we pass in the page so we're just putting the url together by using variables and actual string and to do this the easiest way is to just use backticks so using a string literal and that's what we're doing here and then lastly i'm going to do end we're going to pass in the size which is the key the value is going to be whatever they pass into the function so they'll assign open and close and then we're going to pass in the size so size so this is how we format our url so that you can look exactly the way that we want it to look and then now we just have to define this guy here and i'm just going to set it to the local host so we're going to say local host colon 8085 so this is the back end so that's the default of the back end we're going to put http colon double forward slash and we can make this private read only [Music] okay and let's give it the type here this is supposed to be an equal sign so the type of the server euro is a string and this is the default value for it and it's read-only so it can be changed inside of the class so this is what you would typically see whenever um you see that people are using angular and they're trying to define a function to make an http request to a backend api that's typically what you would see which is a procedural approach but what i want to do is to take a reactive approach so i just want you to see what you would typically see um when people are using angular to make back-end api calls when they're creating a service and then they're making a function to make a call to a back-end this is what it would look like but we're gonna take a different approach and that's what i'm gonna show you right now instead of creating a function that we can call like this i'm gonna directly create an observable so i'm gonna copy this and probably comment it out if you guys want you can use it and also by the way there's nothing wrong with this approach i just prefer the other approach that i'm going to show you and then i'm going to give me some room here and i'm going to paste this and i'm going to call it users because it's an observable of users i'm going to put a data sign at the end so usually when you define observables you put the dollar sign in the end that's how you denote an observable and i'm going to set it equal to the observable and just going to be the same thing going to remove these and remove the return as well and then just set it equal to an arrow function so just like that so it's really the same thing um if i can put this on the new line so you see that i'm just returning the same thing it's just in a different way i just put it in a different format so instead of a return i put an arrow function here and then i pass in the same parameters to the function i just give it a different name of users because now it's unobservable and it's pointing to this other observable because the get users here or the get method here is returning unobservable and we can see that if i press ctrl and click on this get here you can see it returns an observable of whatever type that we pass in in here okay so since this is returning an observable since we're using an arrow function here which is pointing to this observable so therefore this user is unobservable as well and that's really all we have to do it's really just the same thing i just prefer the other approach so now um what i want to do is to get rid of this any here because we're using typescript and we really don't want to be using any unless you really have to so i'm gonna go and create another uh folder here instead of the app folder and i'm gonna call it uh interface you can call it um something like domain or something uh but i'm just gonna call it interface i prefer interface and then inside of there i'm going to create a new file so right click new file i'll just click on this icon up here and i want to create the api dash response dot ts oops i put ta ha rename to yes okay and then inside of this file i'm just gonna export an interface so i'm gonna say export interface and then i'm gonna call it api response this is going to mirror exactly what we have in the back end so just to make sure you can make the connection in a in an easier way let's go back to the back end and let's go look at this response i'm going to collapse this for now so remember we have all of these values in our http response which is what we're going to get and the data is what's going to contain the page of all the users which is going to be here okay so copy all of the properties that we have on this class and then i'm going to go here and paste them in okay because we want to map everything here and then i'm gonna select the first protected do ctrl d until i get them all selected and i'm gonna press delete delete i'm gonna select all of the string do the same delay delete select all of the well i only have one in it so i'm gonna delete that delete that as well in this map which is the data i'm just gonna delete all of this as well so now i'm gonna give this type so the timestamp is gonna be a string i'm gonna copy this the status is also going to be a string the message is going to be a string the status quo is going to be an end so i can put number here okay and then the data is going to be an object so i can do colon open and close curly braces and that's going to contain a page and that's going to be of type let's say t so whatever type we're going to pass to this api response that's the type this is going to be and then i can define the t here so that can be passed out so that's our response we have a timestamp status code the status the message if we pass any message and then the data which in this case is going to be a page of whatever type we pass in here or in our case it's going to be a page of users instead of a user so now let's go ahead and create the user as well so in here i'm going to say new file and it's going to be the user.ts because we need to map everything so export interface user put in close curly braces what we have on the user is an id that's a number we also have the name that's a string we have the email that's also string status which is also a string and then we have the address string we have the phone another string and lastly we have the image url also another string so this is the user pretty easy and straightforward it's the same user that we had in the back end we're just mirroring that in the front end so that we can map into this whenever we get the response back from the from the api and lastly we need the actual page so i'm going to go inside of you again click on the no file icon and then we're going to call this page page.ts okay so this one is going to be pretty interesting and i'm going to show you how i did this uh very quickly so let's go back to the back end so click on run so the back end is running we left it running what i'm gonna do is to just go ahead and see what the response looks like when we get it in the browser and i'm just gonna go ahead and copy that and paste that in here so let's go back here open a new tab and i can actually copy all this stuff paste it in here and i need to change the port so 8085 for slash users okay so this is the the information that we get so i'm gonna see if i can make this a little bigger so we have a lot of information here so we can't really see this very clearly so i'm going to copy it and then open a session with my user because i have a an extension that makes these look pretty and i'm going to move it over here okay so this is the response that we have remember we're mapping the timestamp the status code the status and the message now what we have to map is the page that's gonna be inside of the data that we're defined in the http response so i'm gonna go ahead and copy all of this stuff i'm not gonna include the last one because if you scroll up all the way to the top you see that i'm not including that one as well actually i have to skip two of them the bottom i don't need that last one and then i'm gonna copy all this okay and then i'm gonna say export interface page and then open and click color braces and then i'm gonna paste this in there now we're gonna have to clean this up this contains the actual values and we don't want the values so let's go all the way up so the page is this page that we're defining which means we don't need to have this page again here so i'm going to remove that first line here in line two and go to the bottom which means we don't need that one either okay so now what we have to do is to just go up here we know we're gonna have a content which is gonna be an array and this array is gonna be on array of users as you can see here so this is pretty easy to define so i'm gonna select the beginning of the array to the very end of the array so all of the users inside of it delayed it and then i'm gonna say this is gonna be an array of users so i'm gonna say user array and then import the user okay so this is gonna be the content now i want to remove all of these quotes so i'm gonna do that later because when you have the quotes it helps you because you see exactly what you're doing but once i'm done then i'm gonna use the visual studio search and replace and i'm gonna replace everything here so now we have the empty which is gonna be a boolean so we can select all of the true so select everything that's true here and then we're gonna change it to the type which is a boolean and we're gonna do the same for false so select all the false here with ctrl d and then change it to the actual type which is the boolean not the value so for all of these there are going to be numbers so everything that's 0 10 100 all of these are going to be numbers so we're going to say number and i'm going to see if i can just copy this do it as quickly as i can select all of these paste and i'm gonna remove that extra zero and i'm gonna select all of the zero ctrl d okay i only have to change it to number so now i know there's a first which is boolean last which is a boolean and then i have the array of users here so now i'm gonna select this double quote do ctrl f paste it in there and then i'm gonna say replace with nothing and then i'm gonna click on replace all uh let's format this document a little so this is the page this is what the page looks like it's gonna have something called content which is gonna contain the data which is gonna be an array of users and it's gonna have pageable sort offset page number total elements total pages all the other things that we need uh this is giving me an error i'm gonna just delete it and import it again import i'm gonna replace them with single quote that's nicer so this is the page this is what the page looks like this is the format of the page now we can go back to the api so in here we can pass in this data but we're not going to do it here because we make this api response a generic so we can just pass it whenever we're going to use this information so i'm going to copy this go back to the service i know this is going to return an observable of my api response and for my data so we're going to have an api response which is going to contain timestamp status code status message and the data which is of type page which is a page that we just created here inside of the page is where we have the array of users everything is nicely mapped and we can step into all of these objects if we want because we know that whenever we get a response from the api then everything is going to be mapped into this object here i hope that makes sense and i'm also going to make the same changes in the one that's commented out so i'm going to select the two endings here passing the actual type okay so if you want to use this function feel free to use it but in my case i'm just going to use an observable here so now let's go ahead and start using this observable here so that we can see what we get when we make the request to the backend so let's go into the app component and i'm just going to right click and close all of these tabs we're going to go inside of the appcomponent.cs so the first thing i want to do is to define a state for the application so i'm going to call this user's state with a dial sign because it's also going to be an observable so i'm going to say the type is unobservable and remember the observable is a generic so i need to give it what type of observable this is going to be so i'm going to just put in a literal object in there what i want is an app state so the app state is going to be a string and then i need the app data so the app data i'm not always gonna have data so i'm gonna make it optional and then i'm gonna say this is gonna be of the same type that's coming from the response okay so we can go inside of the service uh in here scroll over a little just copy this response so this is the type of response or the data that we're gonna be expecting i'm gonna paste it here and then we can possibly get an error uh also optional because i adjusted passively we're not going to have an error every time and this is going to be of type http error response so this is technically the application state i'm just calling it the user state because i know i'm going to be working with a bunch of users but i usually name the state whatever component that d would be in so if we had routing and i had like a user's component that would make total sense because we have the user state but you get the point now let's go ahead and import all these so the area is going to go away and we get another error here and if i put this on here you see that typescript is giving me an error it says hey this is not initialized so for example it wants us to say this can be equal null or undefined or something like that and i usually don't want to do this i feel like it's a little bit annoying or too strict so i'm going to show you how you can make typescript stop bothering you i don't want typescript to be so strict with me but if you want you're going to have to say this can be whatever you define or undefined for example or null and then you're gonna have to say it's equal by default undefined so if i do this now if i scroll to the left you can see it doesn't complain anymore but i don't know i don't i don't like to do this i want to just define whatever i want to define and i don't have to give it on the initial value so that's why it's complaining here so what i want to do is to just disable this because i don't want to have to deal with this so i'm going to go in here go to the csconfig.json so right after the strict i'm going to put another property here which is the i think it's strict property initialization and then set this to false because i don't want strict initialization and while i'm here i want to pass in another one called strict uh null checks okay so that one then pass it to false okay so i like to have these two defined in my cs configuration so i'm gonna close this now if you go back you can see that i don't have to set it to anything and it doesn't complain anymore so now moving on the next thing we have to do is to define a constructor and then we're going to do dependency injection so we're going to call the user service of type user service make sure this is imported and this is going to be the constructor and we want to make the request as the component is loaded or is initialized so for this we're going to have to implement the ng on init which doesn't take any parameters and it returns void all right so all the code is going to go in there and we also have to make sure we say we're going to implement um on init okay this is coming from core so angular core and this is on init capital i okay so on init so this function is gonna be called as soon as the component is loaded so once that happens then we want to make the http call so in here we're going to say this user state so i'm going to set my state equal to something in this case that's going to be the service that users remember this is returning on observable so on initial page load we're not going to pass in any of these parameters okay because we want to load everything for page 0 we want to load the first 10 users so this by default is going to be an empty string which is why i'm able to call the function just like this without passing any parameters and then here we're going to pipe this so what i want to do the first thing is i want to map this response so i'm going to say map whatever response that i'm going to have remember this is going to be of the same type so can copy this right here paste it here so the type of the response is going to be of type api response and then inside it's going to have a page and then i can say whenever i get a response i want to execute some code in this case i'm just going to say first thing is i want to console that log this response that's the first thing i want to do because we want to be able to see oops response we want to see this response so i'm going to log it and then i want to return the state that would define here remember we can't return this http response because we have to return something that matches this type here that would define so to do this i'm going to return and in here we can pass in an object so i'm going to say open and close curly braces and i'm just going to copy all this and then paste it in here the app state now we have to give it a value i'm gonna say the app state is going to be app underscore loaded so i know the data has been loaded because i'm able to get the response i didn't get on there appdata is going to be the response so i'm going to copy this and paste it here and we're not going to get any error because if we get a response then there's there's no error and i'm going to remove this question mark all right so that's the response the other thing i want to do is after the map so you can see the map begins here and actually we need to enclose this in parenthesis so the map begins here and it ends all the way at the bottom here so what i want to do is put another operator here which is called start with because whenever this is loading we make the request to the back end we want to start with a state so here um we can pass in a different object so i'm going to copy all this paste it in here and we're going to change this to loading and we don't have any app data we don't have any errors okay so the application is just loading and then lastly if we get an error we're going to catch the error so we're going to call catch air and if there's an error we're going to say the error is going to be of type remember ac response so we're going to copy this paste it in here so if there is an error then what are we gonna do we're gonna say um we can just straight ahead just return an arrow function here like we don't need any return or anything like that and i'm gonna return an observable of some kind of value here when you call of then it returns an observable and then here uh we can pass in something else here paste this so i'm gonna say app air and then the air is going to be the error so i can remove the data if there's an error there's no data and then passing the error like this and we're getting a bunch of errors because we need to import all these things so let's import this from our xjs and import of from the same package first we need to import this error and we need to import this from okay so it's imported as you can see up here and i'm going to remove this and i think we need the closing parenthesis here all right so that looks good i'm just going to go ahead and format the document so that everything can be aligned and all of this needs to be inside of the pair and parenthesis as well right so we're going to catch the error which is going to type http error and then we're going to return an observable that's going to have the absolute error and then we're going to have the error inside of the same state as well uh format this one more time okay so this is what we have so whenever now we go to the home page we should have this log here and we'll be able to see that we actually get the page from the backend so let's go ahead and check that out in the browser so before we go to the browser i'm gonna do control backtick we had errors because we were like writing code and stuff so you can see at the bottom everything was successful so i'm gonna do control tactic so if we go to the browser now you would expect that we're gonna see this console log so let's go ahead and check it out and see what happens so i'm gonna go up here and i'm gonna right click open the developer tool go to the console clear zoom in a little and then i'm going to refresh so you see that we didn't get any errors or anything like that but we still didn't see the log that we have in the code why do you think this is happening why we're not seeing our log and the code here in the console well if you said that is because we didn't subscribe to the observable you are absolutely correct let's go back to the code so if we go back to the code again you see that we have an observable here remember if you don't subscribe to unobservable it's never gonna fire so even though we have this nice code written out here this code is never fired because there's no one that's subscribed to this observable here so for us to be able to see this code in action or for this code to run at least we need one subscriber that would be interested in this data so that the observable can fire itself so that's why we didn't see anything in the browser so to do this um let's go ahead and open the html file and i'm just gonna do a quick demo here so i'm gonna put two double curl braces and i'm gonna say user state um i'm not gonna type this all out i'm just gonna copy it here and we're gonna say user state oops and then i'm gonna say a sync that's how you subscribe in the ui and if we want to see everything i'm going to put another pipe and i'm going to say jason so this is going to show us the state and json format so the async is subscribing to this observable and the json is going to display it in adjacent format so now if we go back you see now we get an error which means the code was executed but we get an error because course has been black for this 4200 to the backend because they're not on the same domain so now you can see the call is actually being made but the backend is failing us because we have a course issue here because the browser enforces this uh course from different origin uh rule so because the front end is on locosphere 200 and the backend is on localhost 8085 then the browser say hey you can't communicate or with this other domain because it's a different domain so we just have to put a configuration in the backend code to tell the backend that hey if you get a request coming in from localhost 4200 just accept it and then it will go through but you can already see from the request that was made that we get exactly what we were looking for so this is the url that was created so slash users question mark name equal empty so we don't have anything there and the page is 0 and then the size is 10. so we know that our url is being formatted correctly so hopefully the call will be successful whenever we fix this course issue so let's go ahead and fix the course issue in the back end and then we're going to come back here refresh the page see if we can see the data so let's go back to the back-end code close all these we want to go inside of the main application file and this is something that i usually do every time i'm working in the backend and building api so i'm just going to go ahead and paste it so if you've seen anything that i've done before in the past with spring boot with angular in the front end then you know this configuration is something that you're gonna do every single time and it's just a simple course configuration we're just telling the browser or telling the backend what request from who they should accept okay so i'm just saying accept requests from localhost 4200 and then make sure everything is imported at the top i think intellij should have done this for me okay so that's all we have to do just put the course configuration i mean you can go through this code but it's going to be the same every time you might have to make a few changes here and there but the bulk of it is going to be the same because you're just going to say hey this is what i'm allowing in the back end and the browser is going to read these headers and it's going to like okay i'm going to allow 400 to go through so i'm going to go ahead and go to the run and then click to rerun the application so the backend application and let this come up okay should be pretty fast because we don't have a big application here go back to the front end now let's see what we get so if i go ahead and refresh you can see we get the data now this is huge that's because we're printing out this big object in the in the header so we're going to put that somewhere else but you can see now that we get the response okay so we get the response which is the timestamp status code status message and we have the data which contains the page you can see here which is an object if i extend this extend the page we have the content which is the 10 users you can see here and then we have all of the information about the page and this is the information that we're going to be using to create this pagination that you see at the bottom here the same object that you're looking at here is the same object that i'm showing here but this is all black and let's go ahead and fix that just so we can see something here open this so instead of putting this in the nav bar just gonna remove it here let's put it like at the top of the table here and then go back to the app okay so you can see here this is what we have so and i can assure you again um if we put a delay on the back end we're gonna have a different uh app state because as of right now if i can zoom in a little more the app state is uploaded update is the entire response that we get and we don't have any errors okay so everything seems to be working fine no errors or anything so now we can start using this data to show something on this table right here and that's going to be pretty easy because you can see that we can already see everything that we have here now what i want to do is to work on this table here so i want to make sure the table has the proper headers and everything so that we can display the 10 users and after we display the 10 users then we're going to get to the pagination which is going to be really interesting so let's go ahead and start working on the table here to display all of these users so let's go back to the code okay so i'm gonna go ahead and just copy this and cut it out because i don't want to keep it here i'm gonna go all the way to the top and the first thing i want to do is to put everything inside of a ng container so here i'm gonna say ng dash container okay and then i'm going to close so inside of the ng container is where i'm going to check to see if the state is defined so here i'm going to put a dollar sign or asterisk instead i'm going to say ng if set it equal to some value and i'm going to say if the state so the state right here is defined we don't need the json anymore because we're just describing and we don't need the curly braces anymore i'm going to remove this space as well so we're going to say we're going to subscribe to this observable so we're going to say ng if the state is defined a sec because we need to subscribe to it and then we're going to give it an alias as state okay so that it can be easier to work with throughout the rest of the template so that we don't have to keep typing this user state here we're just going to give it this alias or this local variable name of state and then what i want to do then is to just switch on the different state so now i can just say um here i'm going to use ng switch so i'm going to say ng ng switch okay we're going to switch on the different cases or the different states so we're going to say state which is a local variable and we want to switch on the app state so the app state here if you guys remember it's going to be either uploaded loading or app error because then i can use the different states to show different pieces of ui depending on the state of the application so this is really cool slash advanced angular that i'm showing you guys here i'm going to cut this here put it at the very bottom because i'm encapsulating everything inside here and just to not throw you off with this router outlet i'm just gonna remove it okay so everything is inside of the ng container so none of this is gonna be displayed unless the state is defined even if it's on air but if it's normal or if it's undefined then nothing is gonna show on the page you might want this behavior you might not want this behavior but the reason that i like coding this way is because either way i'm going to get some kind of state either loading because you remember i'm starting with loading so i can show whatever i want on loading so you didn't have to put this if statement all the way at the top you could have put it anywhere you want in the ui and then show whatever piece of ui you want to show when the data is being loaded but i'm just gonna keep it at the way at the top oops all right so now we have a switch case that we can use to check which state that we're in so the first thing is i don't want to do anything inside of the nav so i'm going to collapse the nav but after the nav i want to show different pieces of ui inside of the of this column here okay so wherever we're going to have the main content of the page that's where i want to show different states so i'm going to go in here and then do ng container again so i'm going to say ng container and then close it and then we want to switch case on the state of error first so i'm going to put another asterisk and then do ng switch case okay so we're going to say if the case is we're going to look at app error so let's go here and just copy this name just so that i don't misspell it and paste it in here so if there's an error then this piece of ui will be displayed and i don't want to do anything fancy here i'm just gonna say from the state get the error and we're just gonna display it as a json so we're gonna say json which is just another pipe so we're gonna see the whole object of the error if there's an area that occurs here whenever we make the call to the backend so that's the first case and then i'm gonna put the second case the second case if when the app is loading so let's just copy this name paste it in here now it would be nice to show some kind of a loading spinner or something whenever the app is loading right that would make complete sense so that's what we're going to do here so let's go back and open google again go to bootstrap press enter first link document or documentation in this case and we're looking for a spinner so spinner um i have a few choices here we can go with the black one uh we don't need anything fancy with colors but feel free to choose either one but i'm just gonna go with the with the black one uh maybe maybe the gray one instead of the regular black we can go with the gray but either way it should be fine but i'm just gonna go with the black all right so now let's go back to the ui so in here we can put everything inside of a div just to make sure this is in the center so i'm gonna do dot d flicks and we want dot justified uh no not justified justify content uh center and i can also give it a margin top of 4 just to make sure it doesn't stick all the way to the top and i'm going to press enter that's going to create a d for me with these classes and i'm just going to paste this in there so if the state is uploading then we're going to have a spinner that's gonna display here it's gonna be in the center and it's gonna say loading i don't know if i want this text in here because we're just gonna have a loading spinner but it's up to you you can remove it you can keep it doesn't bother me here so that's good now if we go back and go back to the app this is probably gonna happen so fast we're not gonna see the spinner but let's just refresh it just to check okay so you see the spinner was there for like a split second and then it disappeared let's do one more time okay you saw the spinner and then it disappeared i'm gonna zoom out here uh shrink this in a little and let's see if we can simulate that so let's go back to the back end and close this uh let's go over to the resource so in the resource we're gonna actually do two things here the first thing is we're gonna put a delay here just so that we can see the spinner in action and then the second thing we're gonna do we're gonna set this to throw an error so the first thing is we're gonna put the delay so we're gonna say let's do time oops time unit dot second dot slip let's do three seconds okay so this throws an exception let's just add it to the method signature this is temporary we're gonna remove it i just want you to see the spinner and really make you understand why i'm designing the ui the way that i'm designing it so let's go to run rerun make sure this comes up okay restarting all right so now if i reload this page you're gonna see the spinner for three seconds because remember if i can bring the code back up we're starting with uploading okay because that's what we're seeing in this observable whenever this code runs this observer is going to make a call while we're waiting for the request to come back we can actually show something else or return a different state or a different value to the state which is going to be just ab state is loading which is what we're checking for so let's go back and refresh you see loading and then we get the data you see the data appears on the right then it goes away because now we have to show different piece of ui now if we didn't want to see the user list at all of course that's what we're going to do because we don't want to show the table unless we have data so let's go back and do that so we're going to go back here and go back in here scroll down you already get the idea we're only going to show this table if we get some data so we're gonna i'm just gonna go ahead and copy this switch statement here and then we can show the user list um but i don't think we should show the user list at all we're just gonna put the title and the table inside of the switch case unless we put this spinner inside like under this like we're not going to show the table but we show the spinner where the table is going to be but in this case i'm just going to put everything in there so i'm going to go here and copy everything so from the title to the end of the table actually we can just take this entire thing okay we don't want to show any of this information including the pagination unless we get some data so now we're just going to check for loaded loaded okay so when the data has loaded we know we get some data from the backend then we're going to show the user list and the table now if we go back refresh now we see the spinner three seconds fast then we get the table okay so that's a better behavior and now um let's see if we can simulate the error because we have three cases we have to account for let's go back to the back end where is my back end here there it is so after three seconds we can do throw new run time exception and then we're gonna pass in a message to say uh force exception for testing okay and now we can temporarily maybe comment this out okay and we run so what's gonna happen is the app is gonna run it's gonna make the call to the back end it's gonna wait for three seconds the whole time the spinner is gonna be spinning and then after three seconds the app is gonna throw this exception so it's gonna throw an error like a 500 error will show the error on the page so now if we refresh we get the spinner spinning after three seconds we get the error you can see the air okay so um you can pick whatever information you want in this area like if i zoom in a little you can see there is like a status a time stamp there's a message http failure response for this specific request or this specific url you can use whatever information you want here just put you know state dot error dot and then whatever a property you want to step into here so that's up to you whatever you want to show to the user definitely not going to show this because they don't want to see all this stuff this is probably going to scare them away so make sure you use you know show something friendly or something like that or you can even do i can show you a quick example actually so you can see whenever there is an error you can say um give me a span and then maybe give it a style color red and then you can say something like um there was an error simple as that and then if we go back now it's gonna spin for three seconds there was an error okay you can either put a static type 10 message or you can use something from the back end or something like that it's really up to you i just wanted to show you how easy it is to do this because we're really uh switching on the different states of the application okay so let's go back and let's just put it the way it was i'll leave that up to you however you want to do this ctrl z uh ctrl y okay so now we have the three states that we can work with so everything looks good now the only thing that we have left to do is to loop over the users and then display them on the table so the first thing is we have to define the different table headers so that's what we're going to be working on next so let's go ahead and work on the table head so we have the id second thing i want is the photo and then i want the name and then i want the email and i'm just gonna copy this and paste it a few times one two three so after the email we can put in the phone and then maybe the status and then we can pass in lastly the address [Applause] so this is the head of the table we can double check just to make sure we get this correct oh we gotta fix the back end uh we don't want this anymore but i'm gonna okay i'm just gonna put it here and then comment it out just so you guys can remember what was done remove that okay so we're still gonna wait for three seconds just to make sure we understand what's happening but feel free to remove that too if you want okay all right that looks good so now if we refresh loading and there is the headers so id photo name email phone status address that doesn't look good because we haven't put in everything for the table role we're gonna do that right now and we don't need all of these because they're gonna be dynamically generated we're just going to need one because we're going to loop through all the users to generate this data we want to look over the table row because that's what we're duplicating or we're looping over so here we can use the ng4 because we're trying to loop on something let user of and then we want to go to the state dot app data dot data dot page dot content okay i hope you guys remember where this is located and if we want to see the index we can say let i equal index it's pretty simple just like that index so that's how we're going to loop through all of the users let's go here and pass in the user dot id we need to pass in the picture of the user so inside of the table data we're gonna put an image so img and then we're gonna put the source so src equal to user dot image url just so that this doesn't blow out of the screen let's give it a width of maybe 42 and a height of 42 and we can give this some bootstrap class so rounded uh circle okay so this is just a bootstrap class and we can probably give it uh let's say an uh alternative so we're gonna say alt and if the picture is not being displayed then we pass in the name of the user so user that name and then we can say uh something like plus and then photo like that so if the image is not displayed for whatever reason the backend fail or it's a bad url then we can have the alternative that's gonna say whatever the username is photo we can put escape s okay like if this is john smith so that's going to be john smith's photo that's a little trick you can do here and then after that we need the username so i can change this now to level calibration is user.name and the next one is the email so double curly braces user dot email and gonna copy this and paste it down after the email we're gonna have the status and the address so after the email we're gonna have the phone and then the status after the status we're gonna have the address okay i think we should be good so let's go back there we go you can see we have our 10 users all the information is being displayed and everything looks good and i'm going to refresh the page just so that you can see everything in action it's loading and then we get the data one more time we're loading the data and then three seconds there we go now the next thing we need to do is to show the pagination so we have to show how many pages there is for all these users in the database because we're only querying the first 10 so we have to use this information of the page that you see here so this information which is the page coming from spring spring data so we have to use all of this information so we know we have a total page uh a number of ten so total pages is ten so we should have one through may uh ten here as a total pages and then we should make all these things uh clickable and everything so let's go ahead and start working on this next but before i want to fix the status because we have to use uh the bootstrap badge to make the status look uh a little a little prettier let's do that real quick before we jump into the pagination so let's go to the uh back application again so in the status instead of passing in the status like this i'm just gonna pass in a spin so go on a new line and then i'm gonna say give me a spin inside of this pen um i'm gonna give it a class of badge okay so that's the main batch class and then i want to pass in the status so inside of here i'm still gonna have the status but then i'm gonna give it another class dynamically and to do this i'm just gonna use ng class and then i'm gonna put some condition in here so the first condition is i'm gonna check what the status is so i'm gonna say user.status and then i'm gonna check to see if it equals active so active then i'm gonna put the background of uh success so i'll put a question mark if that's the case then add this class which is gonna be bg uh success otherwise so the column don't put anything the reason i put a space here is because i think what's gonna happen is these classes are gonna be put together i don't know if angular is gonna add a space in between or anything but i just add the space just in case so that i can have the other class after space from the first class okay so i hope that makes sense so now at least for the active one we should see that there they have the background success so let's go back you can see they have the background success that looks a lot better so now we have to do the same for pending and inactive or whatever so i'm just gonna copy this and you can add multiple condition you just have to add a comma so i put a comma and then i paste it again so i'm going to say if it's pending then we want to add the primaries so here i'm going to say primary the background primary which is the bootstrap blue color and i'm gonna put another condition probably have to put this on a new line the other condition is i'm gonna paste this again is if it's uh inactive so i'm gonna say if it's inactive then we want maybe info and then lastly i'm gonna paste this one more time make sure i put this on a new line though if it's been we're gonna pass in the danger so danger okay so that's all we have to do it's going to be a long string but it's going to do the trick just make sure you put this on a new line because it's better so that it can be more readable i just don't like to put this on different lines really just a personal preference but if i was coding this for like let's say i was working for a company and i was coding this for like the company i wouldn't do it like this i would put it on a no line so now everything should look good okay so this is looking good next we're gonna be working on the pagination which i'm sure you guys are here for uh for the most part so let's go ahead and start working on the pagination one last thing i want to show you before we go to the uh pagination we're gonna change the default data that we have in the service i just want you guys to see this in action so let's go back to the code again and let's go to the service uh the services up here and for example if i say instead of 10 let's say give me give me like i don't know 18 users so the size or the number of row is going to retrieve from the database it's going to be 18. so now if we go back we should see 18 users you see we have 18 users so let's change the page for for example give me page number four so now if you go back so now you see that it starts from 73. so just to make sure you can uh keep this in perspective i'm gonna go back to 10 users and then i say give me page seven so the first user on that list should be 70 or something should be 71 right 71 right so 71 to 80 because we're displaying per 10 and we have 10 pages worth of 10 users i just want to show that you can already see that everything is working like the pagination is working we just want to make these buttons work with the pagination so let's go back here and put this back the way it was so we're gonna put zero by default and then ten users okay so you can see that in action now let's go back to the pagination which is in this nav here okay so you see this entire nav that's the navigation that we have the first thing is this first element so this first li and this last li they're gonna stay because they have the previous and the next i'm gonna see if i can format this a little okay so that the li can be aligned and then everything in between so these three allies they're gonna be dynamically generated which means we don't need three of them we only need one because we're gonna be looping through this and then generate the on the different pages and then in there i'm gonna put this on a new line just so that you guys can see it better that number should probably go in here so you see we have this link here this is where it belongs three things going on here the previous button the next button and all the buttons in between and this is going to be dynamically generated because we have to put however many pages that we have in here we can't hard code the number of pages because this is coming from the back end so before i start coding anything i just want to show you where this data is coming from so if you look at the response look inside of the data you look inside of the page we have the content which is the actual users we're looking for this guy right here total pages okay and i'm going to show you that if we um change how many users we're loading here then we're going to have a different number of pages for example if i go back to the uh not the back end i want to go to the front end again so if i go back to the oops to the service right say i want to load instead of 10 i'm going to load 20. in this case then since we're loading 20 we're gonna have five pages in total so now if we go back you see we load 20 users which means if we look here inside of the page total pages is now five so this is dynamic it depends on how many users we're loading and this is exactly what we want because we want to generate for however many pages we have for however many buttons we want to have in the middle and between these two here so that's exactly what we want so let's go back to the back end to the front and again revert that to 10 close this just wanted to show you so now we're gonna use uh pro first thing is remove this uh this href so remove these and then in the middle we're gonna take care of the previous in the next button in a minute so we're gonna work on this in between so that we can dynamically generate the page number so what i want to do is to loop inside of this li so we're going to say dial assign or asterisk ng4 and then we want to say let page number of and then we want to go to state dot app data and we want to go inside of the data that page dot total pages okay so remember total pages is the number now remember we need an array to loop over things with this format with ng4 we need an array and remember this is a number so this is not gonna work right we can't loop over a number so if we go back here it's broken because we can't loop over a specif a number so what we can do here to make our life easier is to just call the constructor right in here in the template so we can say open and close curly brackets dot constructor right we call it the constructor on the number of pages so we're gonna pass in the total pages now it doesn't complain anymore and then also we can pass in the index we can say let i equal index okay so we have the index and then we have the total pages that we're looping through so whatever page number that we have here it's gonna give us for that many li so if we have five pages then we're gonna have five of these so now i can do curly braces and i'm gonna pass in the index i can't pass this page number because it's it's i don't even know what that is it exists like it's there you just can't see what it is and i can show you that first actually so if we pass in this page number here you would expect it to be something from 0 to 8 or something but it's not it's it exists it's not null it's not undefined but it's just not a number i guess i've been trying to see how i can print this out to see what it is but we're not going to worry about this so now you can see we have one two three four five six seven eight nine ten but then you don't see any numbers so that means that the page number is there it's just not a number which is why we're not going to use it there's another way we can solve this though by using a pipe which if i have time i might show you it's pretty simple but you pass in the total pages and you pass in a pipe the pipe what it's going to do is it's going to take the number and then just create an array out of it and in that case we'll be able to use it but for now we're going to use the index which is also going to work so now if we go back wait for three seconds we have all of our pages but then there is a little bit of a problem because this doesn't make sense to a human this makes sense to a computer hey array starts at zero index which makes sense right but it doesn't make sense for us to show page zero one two three four it's better to show page one to ten instead of zero to nine it's pretty easy to fix we're just gonna add one to this so we're gonna come here plus one so from the user perspective they're gonna see page one through nine but we know it's page zero to one which is what spring data gpu works with the first page is page zero so as we go back we get all of our pages okay so this is the first step and just to show you that this is actually working if we go back to the front end again and go to the service and this time instead of losing loading 10 let's say we're gonna load uh just gonna put an arbitrary number here 35. now it's going to give us a different page number let's see now we look 35 we have three pages okay so you see that is working now to make sure you really get this i'm just going to put 20 here because i know you can do that in your head so if you have a 20 instead of 10 pages we're gonna have five pages because we have a hundred users and now if you scroll down you can see we have five pages so this is working dynamically and correctly the way that we want it to work now the second thing we have to do is we want to make sure that whenever we click either previous or next or either one of these buttons or either one of these li we actually make a request to the backend and we're gonna search for that particular page in the backend so let's go ahead and start working on that and also before i do that i'm gonna change this to 20 because i want you guys to be able to see the bottom here and let's go here and change this to 10 okay back it's gonna refresh it's probably time for us to remove that three seconds we don't need it anymore but anyways you can see now we have our 10 pages and it's in a good spot on the screen where you can see it clearly so let's go ahead and start working on making these buttons work or this allies work so let's go back to the code we don't need the service anymore all right so i'm gonna create another function so copy the existing one go down and paste it i'm just gonna call it say go to page okay this is the function that's gonna be called whenever we go to a different page and then here i'm gonna make it take the name which is gonna be optional okay we don't have to pass the name we can just call the function without passing a name and then we want the page number okay page number is also optional and the type is gonna be a number okay it's going to turn void now what i want to do is to do the same thing the state we're going to set it equal to something right which is going to be this now to start with we're not going to start with uploading because the app is already been loaded so i'm gonna copy the loaded and paste it in here the app is loaded i don't wanna see the spinner again when i search or when i'm not search but when i click on the second page i don't wanna see the spinner you can show the spinner if you want but you don't want the existing data to go away and if we change the state to loading then we're not gonna see the this part right here okay because we're only showing this part which is the table and everything when the state is loaded so we have to make sure that we keep whatever was already on the screen we want to make sure we keep that we don't want to get rid of it which is why this is going to be loaded now the second thing we have to pass is the app data because even if we show the ui if there is no data then it will still crash because we're going to try to access you know these users and they won't exist now if we're going to pass the app data which is really the data on the page we need this data and remember we already got this data when we um make the initial request so when the page loads we get the data here so it would make sense to store this data somewhere and then later retrieve it here because you can see now we don't have access to start with anything because this response only gonna exist when we have a response which is gonna be in here it doesn't exist here because this is what we're starting with before we get the response back so obviously there's no there's no response yet or it's never going to be here because it doesn't belong in this this is what we're starting with so we have to make sure that whenever we get the response the first time we save it somewhere and then whenever we're gonna start with whenever we're searching or not searching whenever we're going to a different page we keep the same data on the screen so we keep the ui piece on the screen and we also keep the data otherwise the ui will be there the table will be there but the app will be broken because there's no response which is where all the data is so to solve this problem like i mentioned we're going to keep a copy of the response here so to do this i'm gonna say um let's create a response uh subject and we're gonna say next and we're going to pass in the response so we're going to say response so we're going to save the response well this is obviously this this doesn't exist yet i'm going to create it in a second so this response subject is going to contain the data so let's go ahead and create that nuclear priority in the class and this is going to be a behavior subject so i'm going to say this is going to equal a new behavior subject and the behavior subject has a type which is gonna be the whatever type that is so this is the type and initially it's gonna start with null so we're gonna say no okay so if you didn't do the change that i did in the configuration when you pass null here it might give you an error so just as a reminder in the ts.config file you need this property okay you need to set it to false otherwise you're going to have to put way more code than you would to make sure that this stop complaining because it's going to complain okay so this behavior subject is going to contain the response because we're passing it in here to this subject so now when we're starting with so we can grab the existing data so this response subject and then we want to get the value okay pretty simple so whenever we click on this function we're going to reset the entire state of the application so we're going to make a request and this request can take some time so in the meantime what is the state going to be we don't want the state to be empty because the app will break so then we say all right then keep the ui loaded so we can keep showing this piece of ui and for the data here's the existing data okay we're accessing the value property and you can see because i typed this the value is of type api response of type page which is exactly the data that we need to pass to app data okay you can see it here it's the same thing here so everything is aligned the way that we want it to be and the air is gonna be the same so if there's an error we're still gonna not show the ui anymore because there was an error and then we can show the error now you don't have to not show the ui you can still pass and load it here and then you just show the area maybe like at the top of the table or something it's really up to you you can take this and do whatever you want with it i'm just showing you an example okay so now um we can get we can take care of this right here now now remember this function take a name so we can pass in the name here even if it's empty whatever the case might be we can still pass it in here and it also take the page so we're gonna say page number and that's what we have to do now the next thing is whenever we get this response we also have to save it because if they click on the next page we want to keep the existing data as well because whenever they click on go to page it's gonna start with this so if this function was called once then it's gonna grab the data that was saved when we load all of the users so the next time they click on go to page then it's gonna use the existing information or the existing data which is all the users so then you will see that the page if you were like for example on page three then you click to go on page four you would see that the ui would go back to page one because this or page zero because this is gonna give you the first page and then it's gonna change when we get the response this is not the behavior that we want which means that when we get this response we're gonna update our data so copy this line and then paste it in here above or below doesn't matter so whenever we go to page we're gonna use the whatever the existing data is we're gonna keep it there when we get the response we're gonna update that data with this response okay so i hope that makes sense so i think that's everything that we need to do for this to work so now we can copy this function go to the ui go down and we need to put this in here okay so what we want to do is to put a click event so we're going to say parentheses click we pass in the name of the function now the function takes a name for now i'm going to pass an empty string and then it takes the page number okay because remember if we go back here i see page number which we're passing into this observable which takes the page number okay so now we can say well the page number is going to be i whatever i is that's the page number whatever the current iteration is that's the number of the page so if we are in the third iteration then the page number is two because it starts at zero we're just adding one here to not freak out our users so now um i can do the same for these guys right here but this one is going to be a little bit interesting and we're going to do it in just a second but let's go ahead and test just this part right now so now if we go back refresh okay next time i'm going to remove this because we don't need it anymore clear the screen and right now we're supposed to be at page zero which means if i click the one it shouldn't do anything it should give me the same data we're going to see the response in the console but the data is not going to change because it's going to be the same data so if i click one it's going to take three seconds then we get the response we still get one to ten because it's page zero and we can see that because if we go into the network actually and we look at the last call you see that we're still looking at page zero you see it right here in the corner fit 0 size 10 and then we didn't pass in any name we pass an empty string so now the data is going to change if we click on page 2. so if i click on 2 it's going to take 3 seconds you see the data has changed okay so we get page 2 which is from 11 to 20. now let's uh fix the back end comment out this code we don't want to wait three seconds and then refresh okay so now you see that this is working and i'm gonna wait for the back end to come up and i'm gonna click on page three okay so we're up and running if i click on page three we should get 21 to 30. 4 5 6 7 8 9 10 100 last user okay all right so we have a few more things to work on we have to work on the previous and the next so let's go ahead and work on those next all right so let's go ahead and start working on the previous and the next let's go back to the code you see that whenever i'm calling this function i need to know what page that i'm on and i know what page that i'm on because i'm looping through this so whatever the current iteration is which is whatever button this is in or whatever li or list item this is in then i get the index because we're looping into this but you see that this li and this other li they're not in the loop so we need a different function that we can call so that we can go to the previous page or go to the next page so what i'm going to do is go back in here and then i'm going to create another function i'm going to call this function go to next or previous page very descriptive and then it's going to turn void all right so now we can possibly take a name well first thing let's take a direction this is more important so the direction i'm going to make it optional it's not really optional in this case but let's keep it optional for now the direction is going to tell me did they click on the forward or the backward button or the previous or the next button and then i want to know if they pass in any name so we're going to say name which is a string so they can possibly pass in a search term we haven't used the name yet but we're gonna use it well we're using it here but we haven't passed any value for it because you see that we're passing an empty string when we do that we get all the users because we didn't specify any search term it's empty string and by default spring just loads everybody i mean according to the page number so it's going to load all the users we need the direction for the backward or previous or next and possibly your name okay so now what we can do we can check to see what the direction was so i'm going to say this that go to page we're going to call the same function and then the first thing we have to pass in is the name if there is one and then we need to pass in the page number you can see the page number is in blue which means that's the next parameter we have to pass so we can do here we can say check the direction see if it's for example we can check for previous or next but i'm gonna do maybe like four okay so if they go forward what are we gonna do we can define another property here we can which we're gonna call current page uh subject and i'm gonna show you why i'm defining everything as behavior subject in a minute looking at the value and then we're gonna add one to it because we know they're going forward so plus one otherwise we're gonna remove one so we're gonna say this minus one minus one oops okay and then close so the direction is what's going to determine if we're gonna add one to the page number or remove one to the page number now we have to define this guy so let's go and use the quick fix to find the property and then we're gonna make it a behavior subject so i'm gonna copy all this and this is gonna be a number and then by default i think we can start with zero so this is the subject that we're gonna be working with and then we can define an observable for that subject so we're gonna see our first thing is we're not going to use this in the ui so we can make it private so the private current page subject we can only use it in that class and then we're going to define current page which is the observable so we're gonna put the dollar sign and then we're gonna watch for this so this current space subject we're gonna watch it as an observable okay so this is how you create an observable like this in the class so by default the page is gonna be zero um we can set the page here as well when we get the response so we're gonna say this that current page subject dot next is how you add value to it and then we're gonna access the response that um i think we have to go to data that page that um we want the number okay this is going to give us the page number so even the page number is dynamic it's coming from the back end and we can do something similar in the go to page so we can come up here we can pass in this page number it's gonna be the same anyway but just to show you something different it's gonna be the same thing so we're passing the page number here which is why now we can use the subject and then check to see which direction we're going to and then we can either add one or we can either remove one and i have too many equal signs here all right so if the direction is forward we add one if it's backward we'll remove one or if it's not forward in this case then we remove one so now we can copy this function go to the ui and in here we're going to add a click event so inside of this link here we're going to say we're going to listen to a click event we're going to call this function in the direction oops so the direction here is going to be backwards okay because they're trying to go to the the previous page so we're gonna say back word and then the name for now we're gonna put empty string okay and we're gonna do the same here for the next one the only difference is it's going to be forward because this is why they click next oops okay so when they click forward or they click next then we're going to add one when we click previews we're going to remove one because this is not going to be forward then this logic will kick in it will remove one so now if we go back all right now if i click next i got 11 to 20 next index and next 50 previous previous previous reviews now there is another problem we are on the page zero technically to the user it's page one but it's really page zero we know that because we're the developers now if i click this what do you think is gonna happen it's gonna fail because we're in page zero then it's gonna go negative so if i click this boom it fails why look if i zoom in page equal minus one that doesn't make sense right the page has to be zero or whatever the last page is but we can't have minus one so that's why it fails so let's refresh this now the way that we're going to solve this ooh this is huge the way that we're going to solve this is whenever the page is 0 disable this button and whenever we're in the last page the save it is button pretty simple right so how we're going to implement this i'm going to show you right now so the first thing i want to do is i want to define some css to disable this so let's go back to the app and let's go to the css file and i'm going to create a class that i'm going to call this a bold all right open and close curly braces and i want the pointer event to be none because we don't want them to be able to click anything and then i'm going to change the opacity a little let's say like 0.5 or 6 or something so the opacity is going to be a little different and of course they're going to have zero pointer event which means when they put their mouse over it it's not going to give them the pointer or anything like that so this is the class that we're going to apply dynamically depending on a specific condition let's close this style for now now back in the ui what we're going to do is inside of this li we're going to add a class dynamically which is the class that we just created the disabled class so remember in here we have this observable which is the current page at any given moment in the application this variable is going to contain the current page of the application so we can use this current page to determine if it's the first page or the last page so that we can apply the style that we just defined to make the button disable or the li disabled so let's copy this variable go back here so in this first one the li not just the anchor element here we want to disable the entire thing okay we don't want them to be able to click on it so i'm gonna go up here put a space and then i'm gonna use ng class again so i'm gonna say ng class and then i'm gonna say there's zero equal and i'm gonna subscribe to that observable the current page and then of course we have to subscribe async and then i'm gonna put a question mark if this is the case then i'm gonna add my class otherwise i'm gonna put empty just like that okay so does zero equal the current page if this is true then i know i'm at the zero or the first page then we can't go to previews because this is supposed to be disabled we're already on the most previous page that we can be on so now i can just say well um let's go back to the css copy this close and then paste it in here put a space and paste it in here okay so we're saying if zero is the current page then this li is disabled let's see if it works it works you see it's disabled now if i go to one i mean if i go to two now it's enabled because we're not on the first page anymore because the page is no longer zero it's it's at this point is one in fact one it's disabled so now we're gonna do something similar for the last uh button here or the last li we're gonna say hey are we on the last page if this is true put the same class otherwise just don't put anything let's go back to the ui i'm gonna copy this entire thing put it on this ally paste now what are we going to be looking for well how we're going to get the last page how we're going to do that so what we can do is we can say well we're going to access the total pages so i can copy this entire thing i go here instead of zero we're gonna paste that in there so this is gonna be the total pages now remember the total pages doesn't start at zero it starts at one so we need to remove one from it and then we're gonna see if it equal the current page if this is true disabled otherwise add nothing so one more time we're gonna look at the total pages so for example the total pages is gonna be from the gpa perspective right now we have 10 pages the total pages that number is 10 but from a jpa perspective it's really from zero to nine instead of one to ten so that's why i'm removing one from the total pages because technically when you go here we load this we know right now we have pages from page zero to nine but jpa trying to make this user friendly and the page the total pages is 10 but really it should be nine because it starts at zero but of course they want to make this user friendly they say it's ten pages which is okay we can still use this data by the way so that's why we have to remove one from it because this is gonna be from zero to nine it's not gonna be from one to ten so i have to remove one let's go back here again remove one which is gonna be nine which is gonna be the last pitch that we can be on if we're loading 10 users so now you see that if i reload if everything is correct and i go to page 10 it's disabled okay so you can see we're on page 10 because we have the last 100th user so last page this is disabled first page this is disabled and that's the vehicle that we want now i see that i don't get any pointer when i uh over over these i want to have the pointer so that the user can see that they can click on this i mean they're probably going to see that anyway but let's go ahead and put a pointer in there so let's go back to the app css i'm going to create another class so that i'm going to call it pointer and then we're going to say cursor cursor pointer okay pretty simple copy this we're gonna edit in all the list element so in addition to page item we're gonna pass in pointer page item pointer page item pointer all right now well we can't see this because it's disabled but we can see that we have the pointers now okay so i click next next next next next next next next disabled because we're on the last page first disable okay we have the pointer working the next thing i want to do is to make the current page selected or to add the active class on it because right now i can see that i have the pagination working but i have no idea which page i'm on when i'm going through the pages so it's extremely important that we show the user what page they're currently on so let's go ahead and work on that next so let's go back to the ui so we have to use this li here we're not worrying about the first one and the second one they're not gonna be involved they're just gonna make the user go to the next page we don't have to make them selected or show that they've been selected because they don't need to be selected whatever we're gonna be selecting it's gonna be in the middle here so those guys right here not the next not the previous these are gonna stay the way that they were so let's go to the code again i'm gonna put this on a new line just so you guys can see type it in a little what we're looking for is this class active not just a bootstrap class so if i do that they're all gonna be active okay because there's no condition even if i go next previews it's it's all active that's how we want we want one to be active which is the one that we're currently on the page that we're currently on so let's go back and um let me copy this class because i want to add this active class dynamically i'm going to paste it next to it and then cut it the class that i want to add is active and i only want to add active if the current page so i'm gonna delete this so if the current page is equal to the page that we're on so instead of zero we're gonna say i so the current page and the iteration equal this guy right here and we have an extra double quote here i need to close this right here there we go so i'm saying i'm going to add this class dynamically so the active but i want to check to see if the current page equal the current iteration which is going to be the page number as you can see here so if that's the case then add the class active otherwise add nothing go back there we go so now i can do next next next next eight nine ten six five four three two one everything seems to be working at least that's one approach that i decided to take to make this work by the way you see that every time we click on on a different page we make a call to the backend you probably don't wanna build your application that way you wanna make sure you put this in a cache locally somewhere possibly on the client so that you can just return it we don't want to make a request for example like if i go from one page two three four five six seven eight nine ten and then i go to page one again if i clear this go to page one again i make another call to the database that's not very performant because i've already loaded all the pages i shouldn't have to make another call to the back and again so definitely don't build your app like this we're not gonna get into caching this time around i just wanna make sure that you're aware of this i mean if your app is simple you're practicing you're just you know trying to up your skills a little that's okay but don't build an application like this you're gonna kill your back end with so many different requests because people are just gonna be clicking all these pages and every time they're gonna send requests you don't want that but anyways the pagination is fully working at this point okay so you can see everything is working as expected all the behaviors we wanted we have them at least for the pagination now what we have left is this form right here so i want to be able to search uh shrink this in a little so i want to be able to search here i want to be able to put the name and search for that user or just put some characters in here and search all the users by that name and then have pagination working for that as well and that's what i'm going to show you how to do next so the last thing we have to do is to make this search user work and let's just go ahead and work on that right now so let's scroll up and see what this form is it's inside of the navigation and it's right here okay so the form is right here hopefully you guys can see it clearly so the first thing i want to do is to give it a reference so i'm going to put the hash symbol and i'm going to give it a name of search form and then set it equal to ng form so ng form so we're gonna have to import the forms module but we'll do that in a second and then we can add the ng submit so we're gonna say ng submit let's get rid of this error because it's gonna be acting weird so let's go back to the app module and we need to import the forms match forms module okay so now we should be good okay so we can call the same function again we can call go to page you can call it search user or go to page but i'm gonna go with go to page but feel free to find a better name for it and then here we can pass in uh well the first thing too we have to do is to give this the ng model so we have to give it a type of oops type equal and we're going to set this to text and then we have to give it a name which is really important so the name is going to be um name okay so that's the name of the user that they're passing in and then we need to make this ng model so now we have a reference for this input inside of this form we can just say whenever we call this function remember we need to pass in a name and a page the page is optional let's just give this a default value so if they don't pass any page number then the page number by default is going to be zero and then the name is gonna be a string so now we can say go to this form reference and then access the value property and then we need to access the name that name is a reference to this name here like if we name this something else like something then something okay so not this name property but the name value which is why we're accessing the value here so let me backtrack on that okay so whenever we call the go to page we're just gonna pass in whatever name that they pass into the input because we're getting a reference from it from the form and we can do the same thing we can copy this and use it everywhere because this reference is in the template so it's available not just in the form but everywhere else in the in the ui so we can go down here and when we pass empty string here we can pass in the name here we can do that we can do that here as well and also here because this reference is on the form it's available everywhere in the ui so now we're passing in whatever value that they pass in for whenever we go to previews or whenever we go to uh go to a page or whenever we go to the next page so let's go back uh actually let's go up make sure this looks good first okay go to page and then we're passing the phone value ng model and all that okay cool so i think that's all we have to do everything should work let's go back all right looks good refresh just to be sure okay looks good now if i put uh f enter you see it works we have all the users with f in their name and i can still go to pagination so the second page has one two three four five users previous works if i put uh let's put something very specific and see what happens copy this remove paste and search we got that one user and of course we don't have any previous or next page because we only have one page and let's put something that's going to return more than one user like a n like i did in the beginning now we have three pages and we can still go to all these pages it's still going to be the same okay all right everything looks good okay all right um so another thing i want to do is if there is no users then i want to return like a message to the user so let's see if we can go to bootstrap and let's look for alerts all right so that second one is fine like this gray one so let's copy the second div let's go back to the ui okay so we're gonna go all the way at the bottom here after the table and we can say something like let's paste this in first so we have the alert and then we can say ng if the state dot app data data data that page dot content that length we're just gonna check to see if it's uh say less than one then we're gonna show this we're gonna say uh let's say no users found okay you can probably test this just delete your database and then see what's gonna happen this should print out instead of the of this okay because this is not gonna print out because it's gonna try to loop and it's not gonna find anything so this is good we can do something similar uh just for sanity check so we're not gonna show this at all so the navi the pagination unless we get something so we're gonna paste the same thing and then we're gonna change this to greater than zero [Applause] so if it's greater than zero the array then we know we're gonna show dispatch nation if it's less which means there's no nothing in the array then we're gonna show this no users file now we probably won't be able to see this because i have a bunch of users and i don't wanna delete my database but you can go ahead and test that it should work so i think this is everything that i wanted to show you guys how to do and hopefully you learned something valuable now one last thing you see that uh let's go back to the front end real quick so if we go to the service by default we're passing in 10 is the size so this is something that you can change you can see that in our code we're not working with the size just the page number well you can include the size the only thing i would say is you probably would have to give the user maybe on the left here the size as a drop down so you're going to allow them to select either 10 or 20 per page or 30 maybe 50 or whatever or all if you want you can give him the all option as well where you load all the users probably not a good idea but you could do that if you if you wanted to so you can take this as an assignment which is to use the size and possibly create a drop down menu here on the left or maybe you can switch this around you put the pagination on the left you put the size on the right but i think the size on the left would be better but anyways it's up to you however you want to design it so i would put a drop down list here which like 10 15 20 or maybe i just go by an increment of maybe 10. so i would go 10 20 30 40 50 60 or whatever and then the user can pick how many users they want to see per page so that's going to be your assignment for this course because i've literally coded everything for you so this is for you to practice now because i know you're gonna go on github and get the code which is okay because that's how you learn you learn from other people's code but you also have to work on your own and see if you can solve problems now if you want you can share the solutions with me whatever you came up with as the solution to use the size you can share that with me i'll be happy to look into it and you know check it out for you you can put it up here as well you can put another input here as a drop down and the user can select either like 10 or 20. i actually almost implemented this i actually started implementing it and i was like you know what i'm just going to leave it as an assignment for this course because i don't have any assignment for this course so that's pretty much everything that i wanted to cover again make sure you don't build your application this way that's going to go into production because you should probably cache the response that you get from every page so that if the user goes from page 1 to page 10 like they click on all the pages then all this data should be cached and if they click back on page one two three or whatever then you don't make a call to the backend but you get the data from the cache so that's another thing i would say to keep in mind but other than that our application looks good the search is working let's search here paste this in search okay we have one person we have one page search everybody we got everybody we can go to the different pages yeah so everything is working so all the code is in the description so make sure you grab all the code from github i'm just gonna leave the links for you guys so just go ahead and grab all the code and uh you can use this as a starting point for your application or whatever you want to build and don't forget to like and subscribe to the channel i'll see you guys in the next one
Info
Channel: Get Arrays
Views: 7,603
Rating: undefined out of 5
Keywords: spring data, pagination, angular
Id: JNxWZXOsU0w
Channel Id: undefined
Length: 150min 16sec (9016 seconds)
Published: Sun Jul 03 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.