Spring Boot and Angular Full Stack Development | 4 Hour Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's going on guys assalamualaikum welcome to amigos code in this video you will learn how to build a fully fledged full stack application using spring boot on the back end and angular on the front end so this course will teach you the best practices on how to structure your applications how to connect your backend to a mysql database also how to build your application using angular and typescript including all of the best practices this course is brought to you by junior from get raise junior has awesome content on his channel and he's been publishing content already on amigos code and you guys seem to love it that's why we keep on bringing more courses from junior but go ahead and subscribe to join the channel he has awesome content his channel is growing and go show some love if you haven't subscribed please subscribe also smash that like button literally just take two seconds or one second actually and smash that like button because that way we can keep on providing you guys with long videos like this where we want you to become a better developer without further ado let's kick off this video what's going on guys junior here and today i'm gonna show you how to build this application that you're looking at and this application is a simple server manager application so you can replace servers with users customers or whatever you want and we're going to build this application from the ground up so we're going to start with the back in which is going to be a spring boot api that's going to be connecting to a mysql database and then once we're done building the backend api with spring boot we're going to start working on the front end where we're going to be using angular to build the user interface that you're looking at right now maybe in the future i can use react.js instead of angular so that i can show you how you can use the same backhand and then use react instead of angular but today i'm going to show you how to do it using angular in the front end in spring boot with mysql and the back end just before we begin i'm going to give you a quick overview of the application that we're going to be building so it's a simple server manager application where we can manage our servers at the top you have the manage servers so that's like the name of the application and then we have this drop down here where you can filter all the servers that you have so right now i'm looking at all the servers and i can also filter by server up and you can see this nice animation where all the servers are filtered and then at the bottom to the left you can see there was a message here that tells me that the servers have been filtered and of course i can filter by server down you can see the message again servers have been filtered and i'm looking at that one server that is down or the status is down so let's go back to all servers and i have another button here that i can click to add a new server so let's go ahead and do that i'm gonna click here and we have this pop-up window and i'm gonna do 192.168.1.62 i think one of the computers on my network is on the 62 and i think this is my desktop so i'm going to type in desktop and i think it's 64 gig so i'm going to do 64 gig and let's say home pc and for now i'm going to keep the status as down so that we can try to ping this server so that we can see when the status changes so i'm going to click on add and i can cancel this and then click it again you see that the form is still populated and then i can click on add and you can see that it's saving all right so the server has been added you can see it at the top here and the status is server down so i can click on this ping here so that i can ping the server and what this is gonna do is it's gonna try to open a connection to the server and determine if the server is up and running or if the server is down or if the server is shut down so i'm going to go ahead and click on this button and let this go and you can see that the ping fails so we weren't able to ping the server that means that for some reason the server is down or we can't connect to that server and i can try to ping a server that is up so if the server is up and we try to ping the server but when we're pinging the server the server is actually down then you will see that the status will change so let's try this one because i don't think i have this 21 on my network so i'm gonna go ahead and click on ping and let this go you can see that the server is down so the ping fail and now the status is server down and that will work for all these other ones as well the behavior is going to be the same and if you look at all these ip addresses you can see that they're all local network ip addresses so all these ip addresses are in my networks on my internal network and i spin up a server on aws so i created an ec2 instance on aws just so that i could show you that it can also be an external or any ip address on the internet so let's go ahead and test this external ip address so i'm going to click on here i'm going to paste it here because i already have it copied and then i'm going to say aws instance and i think this is 32 gig and this is a web server so i set it up as a web server so i'm going to do web server and then i'm going to keep the settings down so i can change the settings to be up as well but i'm going to keep it down just so i can show you that i can ping the server and the service is going to change so i'm going to click on add so that we can save the server all right so this is the iterators instance that i have running in aws so let's go ahead and ping this server and see what happens so let's go ahead and ping it you can see that was really really fast and the ping was a success and now the status is up and we can also delete a server so if we no longer want a server on that list we can go ahead and just delete it by just clicking on this trash icon here so if i click this you can see i have the message server deleted and the server is no longer on the list and you can also print a report as you can see here i have this button in blue on the right so let's go ahead and click it to generate a report so i'm going to go ahead and click it and you can see the server report is down here i can go ahead and click it to open it and i'm going to say yes and you can see that i have all of the information here so i can clean this data a little bit so i can select all the pictures and delete them and delete this one and let's say i don't need these two delayed and then i can put the borders and i can make this a little bigger you can see that we have all of the servers the ip address the name the memory and the current status at the time when we print out the report so this application has some functionalities and if you build this application from the ground up so you build the back end and you build the front end it's gonna give you a very good idea on how these technologies work when you have spring boot in the back end that's communicating with a mysql server and then you have angular and the front end where you're doing all these things with the ui when you're using angular services to make hdb requests and then you're manipulating the data manipulating the ui and all that we have a lot to cover so let's go ahead and get started i'm in spring initializer so that i can bootstrap the backing application and i've already pre-filled all the information on the left so you can see that i've already selected a group id artifact id and a name for the project and everything the package is going to be jar and the version of java that i'm going to be using is 11. you can use java 8 or 910 or whatever just don't go below 8 and on the right i have all the dependencies that i'm going to be using so this is going to be a web application so i have the spring web and then i need the mysql driver and then i have the validations and then i have spring jpa so that i can map my classes to the database as tables and then i have lumbag to help me with ghettos and setters so typical stuff here nothing crazy and i'm gonna go ahead and generate the project by just clicking on this generate button and i'm just gonna save it all right so it's saved as a zip file so i'm gonna go ahead and open this with intellij after i unzip it i have the brand new project open and intellij and i'm gonna expand this folder right here and i'm gonna go ahead and click on the main application class and expand this so you can see that this is a typical swing boot application so the first thing i want to do is to create a folder and then put all the domains that i'm gonna be working with in the application so i'm gonna right click here and go to new and then go to package and i'm going to call this model so you can call this model or domain or whatever else makes sense to you but usually it's model or domain and in here i'm going to create the server that i'm going to be managing so here i'm going to say server so this is the class that i'm going to be creating that's going to represent the servers and the first thing i want to do is to define an id so i'm going to go here and do private and that's going to be of type long and this is the id so this is going to represent the id of the server and this is also going to be the primary key in the database if you've been using jpa then you already know how this goes because we need every entry in the table to have a unique identifier in this case that's going to be the primary key and then we need the ip address and this is going to be a string so i'm going to do ip address and we also need the name so that's the name of the server i need to deprive it first so private string name so that's going to represent the name and then we need the memory so again private string memory and then we need the type so private string type and then we need the image url because every server is gonna have a little image to represent that server so we're gonna do private that's gonna be a string and we're gonna call this image url and then lastly we're gonna have the status of the server so i'm gonna do another private and i'm gonna create an enum so i'm going to call it status and then we're going to call it status so that's going to represent the server up or server down that we saw in the demo of the application and i'm going to come here and create another package and i'm going to call it enumeration and inside of this package i'm going to create this status so i'm going to copy this and right click and create a new class and i'm going to paste it and it's going to be an enum so i'm going to select the enum and then press enter and the servers they're going to have two statuses so we're gonna have server up so i'm gonna do server underscore up so that's gonna represent the server up status and we can put the string in there as well i'm gonna do server on the score up and then we have the server down so i'm gonna do server underscore down also put in the string in here server underscore down and then semicolon so because we have the string that represent the status we also have to define some getters and setters so i'm gonna do private and that's gonna be final that's gonna be a string which is gonna be the status and then i need to define a constructor so here i'm gonna say status and then give it the status so i'm gonna do status and that's gonna be the status and then i'm gonna do this that status equals the study style we got and i don't know if we're gonna need it but just in case we're gonna do another public and that's gonna return a string and i'm going to call it get status and it's not going to take any parameters because it's a getter and in here what i want to do is just return the status so we're going to say return this status and then i'm going to put a space here just so we can see everything clearly and then i'm gonna go here and see if i can import that import class and it should come from our package and that should be all we have to do here and you can see that the error goes away now i see that i'm getting errors in the status class so let's come back here and i see that i'm passing a status here but this is actually supposed to be a string so let's go ahead and fix that and that should be all we have to do to fix everything so now we have the class that represent the servers here but remember we're gonna be saving everything to a database so we need to map everything to the mysql database as a table so that means we're gonna need to put in some annotation here so let's go down here and the first one is gonna be at entity so at entity and then we need to add in a data so that's coming from lombok so that we can get getters and setters and stuff and we also need the no args constructor so no arcs constructor and also the all arcs constructor so all rs constructor so now this is giving us an error because we put the at entity annotation and we didn't specify an id which is going to be the primary key so we're going to come down to the ids by the way this can also be any other data type or anything that is unique on the class it doesn't necessarily have to be an id and i'm gonna do add id so that's gonna represent the id and also we need to tell it how to generate this id so i'm gonna do add generated value from java persistence and i'm gonna give it a strategy of auto because it doesn't really matter in this case so we're just going to give it this strategy so let's make sure we import everything import from java x and import this as well more action import static another thing that i want to do is i don't want this ip address to be empty so whenever we're saving a new server at least we have to get the ip address if you don't get anything else to be able to save something in the database so i'm going to go down here and i'm going to edit constraints so i'm going to do add column and i'm going to pass in the unique so i'm gonna say unique set this to true so what this is gonna do is it's gonna create a constraint on this ip address so that we can't have more than one ip address of the same number so if you try to save something in a database and we already have the same ip address that is going to throw us a constraint exception in mysql and that's just going to make the application throw an exception overall so the user will never be able to save the same ip address twice and then we're going to add the validation so here i'm gonna say not empty so this is why we brought in the validation and then we can also pass in a message for that we're gonna say ip address cannot be empty or no okay so that's gonna make sure that whenever they're sending a request they must send an ip address otherwise this is gonna catch it and it's gonna throw an exception so we have our validations on the ip address the column unique true is gonna create a constraint so we can only have one ipaddress in the database so if we try to save the same ip address again then it's gonna give us an error so that's what this column unique is doing so we're making sure that this is unique in the database and then also we don't accept any request that comes in without having this ip address if it's not or anything like that because we have this not empty so it's going to check to make sure that the ip address is there whenever there's a request coming in with this object and that's all we have to do for this class what we have to do now is to define a way for us to be able to manipulate the data in the database which means that we need some way in the java code so that we can manipulate data in the database so if we want to save a new server update a server or the latest server or list all the servers so we need to have a way in the java to be able to do that in mysql and that's why we brought in the jpa because jp is going to make this really easy so what we have to do is just go ahead and create a new package by the way you don't have to create a package for everything it just helps organize the code so you want to create a separate package for different parts of your application so everything that is related together you want to make sure you put them in the same package so here i'm going to create something called a repository so i'm going to say repo for example so that's going to be the name of the package and then inside of that package i'm going to create an interface and i'm going to do class and select interface and i'm going to call it server repo so we're going to do server repo so repo is short for repository but you can name it repository if you want so what we have to do here is to extend a class called the jpa repository so we're going to extend jpa repository and you can see it coming up here now when we extend this class we need to give it two pieces of information the first piece is the domain or the class that we want to manage in that case that's going to be the server so that should come from our model and then we have to give it the type of the primary key in our case that was the long type and if we go back inside of the server you can see that the primary key here so the field and the class with the id annotation so that's a long type so that's what we're giving to this server repository here we're saying hey we're managing the server so we can update delete read all the servers on the database and also the type is long so by extending this class we have access to a bunch of method that we can use and i can go inside of this class so that i can show you so this is going to list everything we have in a database this is going to list them but also we can pass in a sort that's going to sort everything we can also save some kind of a list or a collection so you can see that we have access to a bunch of methods already that we can use to manipulate the data inside of the mysql server so we don't have to define all this manually but i do want to define one method manually which is to find a server by the ip address so i'm going to say this is going to return a server and i'm going to call it find by ip address so the name here is very important because when you do find buy then you're telling jpa that you're trying to do a select and you want to select by whatever you put here so wherever the ip address equal whatever we're going to pass here inside of the parameter of the function so here i'm going to say string ip address and also this field should exist in your class so i'm going to finish this with a semicolon so the find buy tells jpa to select a server and it's going to check to compare the ip address here with the ip address that we pass in here and another example just so you can understand this so for instance if we know that the name was going to be unique so that when we try to find a server by that name it's going to return one server in the repository we could do something like find by name so just to give you an example i could do something like this so i'm gonna go ahead and copy this whole thing and then go down and paste it and then we can do find buy and then we pass in name and then here we would pass in the name so that would work as well so we would pass in the name of the server we want to find and then find by with select that server by that name so as long as you have this field in your class then this will work and this is a language that you can actually learn with jpe like how to construct your methods so that they can be equivalent to certain sql queries but that wouldn't work in our case multiple servers can have the same name so that's not going to work in this case because if we try to do it this way that's going to say hey i return more than one value and it's going to throw an exception because that's not going to be unique so i'm going to get rid of that but i know that the ip addresses they're going to be unique so i can you know define this find by ip address and i know every time it's supposed to either give me a server or tell me that it didn't find anything any server by that ip address so extending the gpa repository is how you manage your information or your data in the database because this will allow you to save information in a database update them delete them etc and also there is a lot more we can do with the jpa repository but i'm just giving you a small example but you can really take this to the next level and define multiple different methods and by just the name jp is going to interpret the name and be able to sort things and limit things and do all kinds of stuff that you can actually do with sql queries so now we have the model that we want to manipulate so that's going to be the servers and then we have a way to manipulate it by using the jpa repository by creating this server repository that we're calling server repo the next thing we have to do is to define the different functionalities that we want to have in the application and to do this we can define a service and then we define methods that's going to represent the different features that we want to have in the application so i'm going to go ahead and click on the main package and create another package and then i'm going to name it service press enter and inside of the service package i'm going to create a server service and that's going to be an interface so i'm going to select interface and then i'm going to name it server service and press enter so instead of this service i'm gonna define all the different functionalities or features that i want the application to have so i'm gonna go down and i want to be able to save a server in a database so we're gonna create a function that's gonna return the server and it's going to call it create and this is going to take the server that the user is trying to save so we're going to give it a server and what it's going to do is it's going to go ahead and create the server and then save it in the database so let's go ahead and import this and that's supposed to come from our model and everything looks good next we want to be able to list all the servers we're going to create something that's going to return a collection of servers so we're going to say server and let's just call this list so it's going to list all the servers and i'm going to make it take a limit which is going to be an integer and i'm going to call it limit now you could make this take a page because we can also return a page to the user but in this case i just want to limit the number of servers or the number of rows that i'm returning when i try to call this method to list all of the servers so let's say if i pass this limit to be 10 so if i have for example 100 servers in the database then it's going to give me the first 10. it's not going to give me all the 100. and then i'm going to define another one that's going to also return a server that i'm going to call get and this is just going to take the id of the server that we want to find so that's going to be the id and then another one that's going to return the server is going to be update and this is going to also take the server so we can give it a server to update and it's going to take that server with the updated information and it's gonna save it in the database and lastly i need one to delete a server so it's gonna return a boolean true or false i'm gonna call it delayed and it's also gonna take the id of the server so we just give it the id it's gonna go in the database find the server by that id and then delete it and as you can see this is an interface so we're not really implementing anything this is just functionalities that we're laying down that we want to have in the application so we want to have a way to implement these functionalities so that we can actually use them and that's why we created the repo because with the repo we can create we can list we can get we can update and delete so we're going to create an implementation of this server service and then using the server repository we'll be able to create an implementation for all of these functionalities or features that we just defined and you can define as many functionalities or features as you want in this class and you can implement all of them or you can just implement some of them but in my case i only need these five so i'm just gonna define these five and then implement them so in the same service folder where we have the server service let's create another folder and i'm just gonna call it implementation and inside of the implementation i'm going to create the server service implementation so server service implementation and press enter and of course this is going to implement the server service so we're gonna say implements server service so now once we implement the server service of course we have to implement all the methods inside of the service as you can see intellij is helping me here and you can see we have all of the methods that are coming from the server service so all these methods now we have to implement them in the server service implementation because we're implementing this interface server service so before we actually try to implement everything here there is one important method that i forgot to put in which is the method to ping the server so let's go back into the service and right below the first method i'm going to create another function i'm going to call it ping and it's going to return the server that we're pinging and it's gonna take the ip address so we're gonna say ip address so we're gonna give it an ip address and what it's gonna do is it's gonna try to ping that server and then return the server that we were just trying to ping so it's gonna go in the database find the server by that ip address and then ping the server and then return the pinged server and the reason that i'm returning the ping server is because in case the status has changed i can also show that updated status in the ui whenever i get this return server back to me so now we have to go to the implementation and then add this one method so implement method the ping click ok and you can see that it's edit right here so now we have all of the functionalities that we want and now we just have to implement them so the first thing i want to do is to bring in the server repo because with this repository we can actually do all the things that we need to do in the implementation as you can see here so i'm going to go up here and then i'm gonna define private field so i'm gonna say private final and then i'm gonna name it server repo and then give it the same name server repo and i'm gonna bring in an annotation here so i'm gonna go up and then do add required arcs constructor so because i have this required aux constructor lombok is going to create a constructor and then it's going to put this field inside of the constructor and it's going to be our dependency injection so instead of creating the constructor ourselves lumpback is going to do it for us with this annotation and we also need to make this a service so i'm going to say service and also i need to bring in the transactional so i'm going to do transactional and lastly i need to bring in the log so i'm going gonna do at sl f4j so this is gonna allow us to have something printed in the console so that we can see exactly what's happening so at this point we're ready to implement those methods so let's go ahead and start working on those i'm gonna put a space here and i'm gonna scroll up a little and what i want to do in the create is to log so i'm gonna go ahead and do log that info and we're gonna pass in a message so i'm gonna say saving new server and then let's say we want to show the name of the server so i'm going to do open and close curly braces and then put a comma and then try to get the name of the server so i'm going to do server that get name so that's going to give us a log in the console that's going to say saving server and then passing the name of the server the next thing i want to do is to create an image for the server so i'm going to do server that set image url that id and then let's say i'm going to create a method and let's call it set image let's do set server image url and it's not going to take any parameters so let's go ahead and see if we can define this function all right so we're going to create this and for now let's make it return uh like null for example just so that we don't get an error but i'm gonna also move this to the bottom and then we're gonna work on it later so i'm gonna paste it here just like that so we're gonna come back to this and then we're gonna work on it because we need to set an image url for every server that we save and then after i set the image url i can go ahead and save the server so i'm gonna go here call the server repo so we're gonna say server repo and then because we extend the jpa repository we have this save which is pretty much how we save something in the database and then here we're gonna pass it the server so whenever we're using this method to create a server it's gonna log something into the console set the image of the server because we're not gonna ask the user for an image and then we're gonna save the server in the database and also return that server so let's go ahead and work on the second method so for the ping that's gonna be a little bit interesting i'm gonna go ahead and copy the log and paste it here and we want to say something else so let's say banking server and let's pass in the ip so we're going to say pinging server ip and then pass in the ip address so we're going to say ip address so we're going to have something in the log that's going to say banking server ip and it's gonna show us the ip address of the server now remember at this point we don't have the server that the user is trying to ping we only have the ip address and let's go ahead and see if we can find that server so we're gonna find the server we're gonna name it server and then call the server repo that find by ip address and then give it the ip address so just gonna go into the database select the server by that ip address so what we have to do now is to try to ping the server so to do this we're gonna do inet address let's call this address and then do inet address again get by name and then we're going to give it the ip address so we're going to say ip address so this is going to give us the inet address and then once we have that inet address we can check to see if the server is reachable and we can do server that set status so set status and then take the address and see if it's reachable so we're gonna say is reachable and then let's say we're gonna give it 10 000 and after this timeout if we can't reach the server then the code is going to continue its course and then here i'm going to put a question mark and then i'm going to say server up and let's see if we can do a static import for this otherwise we're going to set the status to be server down so i'm gonna go up here put a column and then we're gonna say server down so what are we doing here so we're getting the item address for that specific ip address and then we're gonna set the status of the server so what i'm doing here is just checking to see if we can reach the server within this timeout so if we can reach the server within this timeout then i'm going to set the status to server up because i know the server is up otherwise the server is going to be down so since we edit the status of the server then we have to save the server in the database with the new status so i'm going to call the server repo call save again pass in the server and then lastly we're going to return that server so then we're going to say return server and we're getting an error because this is supposed to throw an exception so we're just gonna edit to the method signature just like that so you can see how this is making sense and i'm gonna show you another slash better way to try to ping a server but this is reachable it's gonna work fine after i'm finished adding all of the implementations for all these methods i'm gonna create another method that you can use if you really want to try to reach a server using the um you know java.net package they have really nice features and methods and things that you can use to see if you can establish a connection with a remote server so i'm going to show you how to do that but for now this is going to work for us this is reachable it's going to work for us at this point let's go ahead and scroll down and we have to work on this list so let's go ahead and copy this log and just paste it here i'm gonna say something like fetching all servers and we don't need the ip address and all i have to do here is to return the server repo and we want to call the find all and as you can see for the find all we can pass a page so if you scroll down you can see there is one where we can pass a page and that's the one that we're gonna use so i'm gonna do find all gonna pick any one of them and then i'm gonna create a page so i can say something like page requests and then i do of and you can see i can pass in a page and the size so i'm gonna select the first one and i'm gonna say give me the first page so page zero which means it's going to start from the beginning and then let's say i'm going to pass in the limit which is an integer so this is going to return a page and we didn't just convert it to a list because we're returning a list and i can do a static import for this so if you really want to return a page you can go ahead and return a page but i want to return a list but when i'm returning that list i also want to limit i don't want to get all the servers let's say if i have like 500 servers the find all is going to try to return all of these servers so i don't want to do that i want to just limit the number of servers that i get back when i try to list all the servers so that's why i pass in this limit by passing the first page so that's going to be page zero and then give me like 10 or 30 or the first five or something like that and then of course since we passed this argument inside of define all it would return a page instead of a list or anything collection so we transform this into a list by just adding that tool list to it and i'm going to go ahead and scroll down and copy the log as well and paste this here i'm going to say fetching i'm going to delete this and i'm going to say server by id and then pass in the id so i'm going to put opening close curly braces and then pass in the id so that we know what id and we're trying to fetch the server for and then all i have to return is the server repository so server repository that find by id as you can see down here passing the id and then we need to call the get so when we call the get that's going to return the actual server that it finds by that specific id so now let's go ahead and work on the update so the update is another save i'm going to scroll up and copy all this and go down and then paste it here for the update and just remove this image because when we update we're not gonna update the image and then i'm gonna say updating server and then pass in the name of the server and this is just another save the difference is when you pass the id then jpa is smart enough to know that it's an existing id like it finds it in the database this is gonna do an update if there is no id or the id is null then it's gonna do a create or it's gonna add the server in the list or in the database and let's go ahead and scroll down now we have to work on the delete so let's copy this log one more time and paste it here and we're gonna say deleting server and then pass the id passing the id like this we can say by id all we have to do is to delete so we're gonna call the repository again call the delete pass in the id actually you have to call the late buy id pass in the id and then here we can go ahead and return true select that and do a static import for this so if this is successful then it's gonna reach this line so that's gonna return true otherwise this is gonna throw an error so we'll never reach this line on line 74. so now it's pretty easy by the way using jpa but i have to tell you when we're working with really large and complex application it's never gonna be like this easy at all and i'm gonna have more content coming out where i'm gonna show you that when you're really working with real world application and things are really complex it's never going to be that easy coding it so smoothly like that but i'll show you in the future that when the application is complex it becomes really hard to use jpa because we want to do a lot more complex operations in the data using sql and because we're trying to do these operations then we're kind of like forced to use sql queries and then pass them into java and then have the application execute those queries instead but for now this is going to do jp is going to do jp is actually very powerful so for a lot of applications jpa should be all you need to manipulate your data in a database i have these four images inside of this images folder as you can see here inside of my downloads i have a folder called images and i have four different images of servers that i want to assign to a server and i want to do this at random so i want to pick a random image here and then assign it to a server whenever we're trying to set the image of the server so what i want to do is to just go down and where we're setting the image of the servers i'm gonna define an array i'm gonna do string and that's on array so i'm gonna put opening in closing bracket and i'm gonna call it image names and i'm gonna set it equal to all these names that i have so instead of this array i'm gonna define the server images so here what did i call them so let's go back to this folder and i have server one server two server three that png is in server for that png so i'm gonna do server one that png and just copy this and do it four times because i have four of them and i'm gonna change this to four change this to three and change this to two so server one server two server three server four and i wanna pick one of these at random and then assign it as the url for that specific server because i don't really care what the server is i just want to assign some image for just to improve the ui experience so i'm going to go down and then i'm going to do well we already have a return so i'm going to use that return so what we want to return is a servlet uri we need the component builder and then we want the from current context path and then we're going to add a path to it and that's going to be a string so we're going to have to create this in the controller later when we're building the resource so here we're going to do server forward slash image i'm going to collapse this for more room so that you guys can see so when we're returning this url it's going to be localhost 8080 forward slash server forward slash image and then forward slash server one dot png or server 2 or server 3. server for that png so we need to append one of these servers at random to this path that we're creating here and the way i'm going to do this i'm going to add a forward slash and then i'm going to say plus and i want to get an image at random so i'm going to do images and i want to put bracket because i want to pick one at random and then i'm going to do new random and that's coming from java util and then call the next ant because i want to get an integer that's going to be the index of the specific image that i want because i have like zero one two three four well i have zero one two three so i'm gonna go ahead and pass four in here and then convert this to a uri string so i'm gonna do that to your eye string and it's gonna return a string and this bound what it's doing is it's making sure that whenever we're creating this random number we never go above three so the four is the bound which means we're never going to reach the four so our indices are going to be zero for the first one and then one two and then three so that way we never go out of bound and that's all we have to do for this method so before i create the controller i want to have a way to send a response to the user so every time i want to send the same response either if i get an error or if i have a success then i want to send the same response to the user so what i'm going to do inside of the model i'm going to define another class i'm going to call it response and this is something that i like to do you don't necessarily have to do it but i like to send oh i made a mistake in this so let's rename this this is response yeah like i was saying i like to use a particular class and then return it every time that i'm building an api so that my api can be consistent so inside of this class i'm gonna do protected and i'm gonna do local date time and i'm gonna do a timestamp for this so time step and i want to do another protected and this is going to be the status code so i'm going to do status code and another protected this is gonna be the http status so i'm gonna do http status and this is coming from spring framework and i'm gonna call this the status and then i want the reason so if i have an error in the application i want to send the reason for the error so this is gonna be a string and i'm gonna do another protected that's also gonna be a string and this is gonna be a message so this is a success message so typically whenever there's a request that comes in and the operation was successful then i'm gonna return this message and the user can use that message in the front end to show like a notification to the user or something like that which is exactly what we're gonna use when we're working on the front end to show the little notification and then i like to have a developer message so that's going to be another string and i'm going to call it developer message so this is a message that's going to be like more technical and more detailed and if a developer want to take a look at this message or they want to send that message over to some other services or something like that in the front end so they can use that message you know something that is meant for developer and then lastly and most importantly is the data and i'm gonna do a map for this and it's gonna be a map of anything and i'm just going to call it data and you're going to see how this is going to come handy in a minute whenever we're using this class to send information over to the user to the front end so this class is going to represent the response that i'm going to send to the user every time there is a request that comes into the application either if i'm sending a success response or a failure response it's always going to be this class that's going to be embedded in the body of the response that we're going to send across the entire application so that our application can be consistent and i also need to add in some annotations so i'm gonna do at data coming from lombok and i'm gonna use the builder pattern so i'm gonna do super builder and lastly i want to only include values that are not null so i'm going to do json include so i'm going to do non null which is this one that i'm looking for and i'm going to go ahead and do a static import for this so what this annotation is gonna do is since i'm gonna be sending this whether i'm sending a successful response or a failure response right so if i'm sending a success response then this developer message is gonna be null because i have no developer message because it's a success this message is going to have some value to it but this developer message in this reason these two are going to be null so because they're null then they're not going to be included in this response at all whenever we're sending it to the front end so that's what this annotation is doing it's really handy when something is null just don't show it at all to the user so i'm going to be using this class as the response body that i'm going to be sending every time to the user whenever they send a request to the application so now all we have to do is to create a controller and then use this class to send responses back to the user when they access our application so now everything is in place for us to expose all of these functionalities over http so i'm going to close all of these tabs and collapse some of these and in the main package i'm going to create another package i'm going to call it resource inside of that resource package i'm going to go ahead and create a new controller class and i'm going to call it server resource you can call this controller but typically when it's a rest controller like a rest api it's usually called a resource but that's technically the controller so at rest controller and then i want to do a request mapping so i'm going to add request mapping and i want everything in this class to leave under server so i'm going to do server and the first thing i need to do is to bring in the service implementation because that's what we're gonna call every time we need to do something in the back end so we're gonna do server service implementation and we're gonna call it server service for example and if you remember if we go inside of the server service we define this as a final field inside of the class and then we use the required arcs constructor which is going to create the constructor and then pass this in inside of the constructor which will be the dependency injection so we need to do something similar here so that's why i defined this as a private field and then we just need to add the annotation in here so once i do this you're gonna see that this error is gonna go away because now we're doing our dependency injection properly so i'm gonna go ahead and collapse this and then go down i'm gonna define a public method and it's gonna return a response entity so we're gonna do response entity and that's gonna be of type response so the body is gonna be the response that we created in our model and then i'm gonna call this get servers so that's going to return the list of all the servers that we have in the application and then inside of this method i want to return the response entity and then i'm going to call the ok on that class and you can see that the ok takes a baddie and for the body we're gonna pass in our response so i'm gonna call my response and since we're using the builder pattern so i can call the builder and then pass in the information that i need to pass so here i can put that timestamp and then i'm gonna pass now and then i'm gonna do data so for the data we need a map so that's gonna be a map of and then we can pass in the information that we need so i'm gonna say this is gonna be the servers so the key is gonna be servers and then the value inside of that map is going to be all the servers that we're going to retrieve so i'm going to call the server service that list and then let's say we want the first 30. so i'm passing in a hard-coded value as you can see here but if you want you can take this as a parameter ask the user for that parameter of course and then pass it in here otherwise you can pass in a default but me i'm just passing in this hard-coded value because i know i'm not going to have you know not more than like 10 or 15 servers at a time in the application and then after i pass the data i can pass in the message so i'm going to say the message is going to be servers retrieve for example and then i can pass in the status so i'm going to say status it's going to be okay and then the status code we needed that so the status code is going to be the same status and then we're going to call the value on that so that's going to give us the actual number so for the okay it's going to be like 200 and then lastly we're going to call build and then i'm gonna press ctrl alt l to see if i can format everything and then see if i can import those so i'm gonna put my mouse on here go to my action import and import this okay as well more action and then okay so all the errors are gone and then the last thing we have to do is to add an annotation on this so that we can expose it so i'm gonna go up here and then put at this is gonna be a get mapping so i'm gonna do get mapping and then i'm gonna give this a route so this is going to go to servers.list and i have to put a forward slash just like that so when we start the application and then we go on the base path so that's going to be localhost 8080 and then for slash server for slash list then it should give us this response that we're creating here and as soon as we finish with this controller we're gonna go ahead and try so let's go ahead and continue with the other methods i'm gonna go ahead and do a static import for this map as well so i'm going to go here at static import and then i'm going to go ahead and copy this function scroll down and paste it so this is going to go to the ping forward slash and remember we need some way to capture the app address so here i'm going to say ip address so we're going to grab the ip address of the server that we're trying to ping and i'm going to change the name of the method as well name this ping server remove that s and here we have to pass in the path variable that we're grabbing in the url so for this we're going to use another annotation call path variable then give it the name that we're grabbing in this case that's the ip address and then we're going to define this as a string which is going to be ip address and then what i want to do first is to see if i can ping the server so we're going to do server define the server here and then we'll call the service so service and then see if we can ping the server so we're going to call the ping you can see it here and that takes the ip address so once we ping the server whether it's successful on that that doesn't really matter we're just going to change the status of the server and as for our data we're just going to return the server so i'm going to change the key and the map to server and then pass in the server as the value in our map everything else is going to be the same but the message is going to be different so this message that we're sending back to the user this message is going to be different so what i want to do is to check to see if the ping was successful or not so i'm going to say server that get status and then check to see if it equals server up i'm going to do server up and then put a question mark so i'm just checking to see if the setting is up if that's the case then i'm going to say ping success otherwise i'm going to say something else ping fail and let's do aesthetic import for that as well so that we can save some space so the message is going to be paying success or ping failure depending on what the status is at this point because we know that after we ping the server if the ping was successful the status is going to be server up so that we can say okay if the server is up then the ping was a success otherwise the ping was a failure because this is going to return false so it's going to jump to this string and we have to add the exception to the meta signature we can just do that here so that we don't have to use the track hatch block and that's all we have to do for the ping let's go ahead and copy this one more time and then scroll up and i'm gonna paste it down and i'm gonna change this to a post request because this is where we're gonna try to save a server and i'm gonna change the url as well to save so it's gonna be save and change this to save server and inside of here we're going to use the add request body because we're going to be sending the body and the request we're going to say request body and i'm also going to use the valid annotation so i'm going to say add valid you can see that it's coming from java x validation which is the dependency that we add in and then here we're gonna say server and then we're gonna give it a name of server and i'm gonna remove this exception because i don't think we're gonna be using it and remove this line as well and this is supposed to be post mapping so we're going to grab the body of the request which is going to contain the server and we also put at valid which is going to check for the validation that we added so if i press control and go inside of the server we're going to check for this annotation here which is the validation so let's go back and what we need to do is to do something very similar that we've been doing so if everything is successful it's not gonna be an okay response so this is gonna be created so i'm gonna change this to create it and then do the same thing below so this is going to give us the tool one which is the status for created and we can go inside of this if we want you can see that 201 is a successful response for created so whenever a resource is created on the server and that's what we're using here and we can also use the created here so if i do control space you can see that there's a created that we can use as well but that takes a uri and i want to be able to send a response to the user so if we use the created then we won't be able to send a response there's another way we can do this by just returning a new response entity and then we can fill in all the class information for the constructor but the okay is also an acceptable response for when something is created in the server so i'm just going to leave it as okay but you can do something else as well so the timestamp is always going to be now so whenever we're returning the response and here for the map for our data we're also going to keep the server because we're going to return the server that got created and here we're going to call the service so we're gonna say server service dot create which is also gonna return the server and then we're gonna pass it the server so this is gonna return the created server and that's the server that we're gonna pass in as part of the data to the response and of course the message is not gonna be paying failure or success it's gonna be server created so something really simple and this message can be anything you want and you can also notice that we're not using the developer message or reason here because we're not dealing with any errors in this case and that's all we have to do for this method so i'm going to scroll up a little bit and copy the ping server method and then go down and then paste it and this is going to be the one to get a server so i'm going to call it get server and we want to make this go to get we're going to pass in the id so i'm going to remove everything and then set this to id the param is also going to be the id and we want to get the id as a long and then pass in the id remove the exception because i don't think we're going to be throwing an exception in this case remove this line as well and everything is going to be the same except that here we're going to call the service so we're going to call the service and then call the get passing the id so this is going to return the server as part of our data and the response and change the message here as well so i'm going to remove all this and then say something like server retrieve and that's pretty much everything we have to do for the get server so we're going to get the id and the path of the url and then get it in here as a long and then call the service to get that specific server and then we're gonna pass it in as part of our data and then everything else is the same so i'm gonna copy this one more time and scroll down and then paste it and this is gonna be the delayed mapping so i'm gonna change this to the late mapping and this is gonna go to delete so i'm gonna change this to delay and we also need the id when we're deleting and i'm gonna change the method name to delay so the late server we're also gonna get the id and instead of get we're gonna call the delay passing the id and then we're gonna pass in the message here so we're gonna say deleted so that's gonna be either true or false so for the data it's gonna be a key of deleted and that's going to be either true or false of course we're never going to say the false because it's going to throw an exception but just in case you never know what can happen so this is going to be either true or false and that's how we're going to know that the server was deleted and then we're going to change the message as well to delete it and everything else is going to be the same so you can see that this is really just a rinse and repeat and that makes everything really easy when everything is consistent you can see that every time we're sending the same response to the front end now the last method that i need to add inside of this uh controller is the one that's gonna read the url for the image of the server and then return the actual image to the front end so i'm gonna copy this again one more time and the last time and then go down and paste this so this is going to be a get mapping so i'm going to delete all this put a g here and remove that e so get mapping and that's going to go to remember this has to be the same path that would define on the server image so if we go back real quick inside of the implementation and scroll down so the path has to be server forward slash image and then the image name so let me just copy this and close out of this so remember this entire class is living under server so we have that first portion of the url and then we want this to go to image all right so i'm going to remove some of those for slashes and we want the image name so that's going to be inside of the url as well so i'm going to say file name okay so that's going to be like server 1 or server 2 or server 3 that png and then we're going to grab the file name and we're going to pass it in here and that's going to be a string that's the file name and i'm going to remove all of this because we're not going to return anything as a response or anything like that all we need to return is the bytes that we can read from that file so i'm going to change the return type as well that's going to be byte and array so that's going to be a bunch of bytes and we're going to say get server image okay so that's the name of the function and i need to pass in another parameter for the get annotation and we have to pass the at here all right so at get mapping so we need to pass in another parameter and for me to be able to do this i have to specify each parameter that i'm passing in here inside of this function so the first one is the path like you already know so we're going to set the path to that so if you're not going to pass on anything else you don't need to say path equal you're just passing the path but if you're going to pass something else then you have to specify the path so that you can differentiate between the different parameters that you're passing and the second one that i want to pass in is produces i want to pass in image underscore png underscore value and close that so let's go ahead and import this let's go to more action and import static constant and it's supposed to come from media type so let's go ahead and select that so if we go in here it's only going to say image.png because we have png images so if we go back and close this we're explicitly saying that this is producing png values so that's going to be some sort of image not adjacent so by default for instance for those functions or those methods they're returning json but here we're explicitly saying this is going to return an image of type png so now all we have to do is to go to that location and see if we can read the bytes for that image and then return that so i'm going to do files and i want to do read all bytes as you can see it's coming up here and this takes a path so i'm going to say paths that get and then we need to pass a new uri so remember this is inside of my downloads inside of the folder called images so i'm going to say system that get property and i want to go to my home folder so that's going to be user.home so that's going to do like whatever my username is and then put me inside of the home folder for that computer and then i need to go to the download so i'm gonna put a plus sign and then do downloads and then i need to go inside of images so that's the name of the folder and then forward slash and then i need to add in the file name so i'm going to do plus and we have the file name that's coming up here and then end this with a semicolon so this is going to give us an error because it throws an exception we can just add it to the meta signature like this so when we set the image url on the servers then when we load it in the browser by default the browser is going to send a get request and that's going to be intercepted by this method and the get request is going to have the file name it's going to be something like localhost 8080 forward slash image forward slash server1.png so we're grabbing the server1.png we're going inside of that folder and then try to read the bytes from the file and that's exactly what we're returning and this is going to return the image itself so that's pretty much everything we have to do in the controller so our application is almost ready to be tested and we're going to be doing that very soon what i want to do is to add in some servers in the database so that we can see something when we try to let's say when we try to list all the servers that we have because if we try to do that right now we're just going to get an empty array it's not going to have anything in it so let's go into the main application file and i'm going to go ahead and close all this so instead of the main application file we can define a bin of type commit line runner and that's going to run after the application has been initialized and then we can just save some servers in there so that when we go to the browser we can actually see something so i'm gonna do command line runner you can see it coming up here and i'm just gonna name it run and give it the server repos i'm going to say server repo give it the same name and then open and close and inside of there i don't want to return an error function so i'm going to do args error function and every piece of code that i put in there will run after the application has been initialized so what i can do is call the server and then save some new servers so i'm going to do new server and pass it null for the id so that gpa knows that this is a new server and i need to pass in an ip address so let's say 192.168.1 for example have to give it a name so let's say ubuntu linux for example i have to give it a memory so let's say this is a 16 gig and then i have to give it a type so let's say this is a personal computer so pc and then i have to give it an image so that's supposed to be http colon double for slash local host colon 8080 and remember it is supposed to go to server for slash image for slash let's give this server one that png and then lastly we have to give it a status so i'm gonna say server up for example so this is really going over so i'm gonna put this on a new line just like that and then put this in my and then see if i can do a static import for this just like that so i'm gonna go ahead and add some more servers and then i'm gonna come back so that we can run this so i went ahead and added four servers here as you can see i have four servers edited with different status and everything and then i'm gonna put the bean annotation on top of this so that this can get picked up by spring all right so now when we start the application we're gonna have something saved in the database the last thing we have to do is to put in the configuration for our database connection so let's close this class and let's go back to the resource so i'm not using templating so i'm going to delete these two folders because i don't need them because this is an api like we're not going to have any html files in here or anything like that and then i'm going to change this to a yemo file so i'm going to refactor this and change the extension to yemo oops lowercase and i'm just going to go inside of this file and then paste the configuration because this configuration is always going to be the same every time so i don't want to have to type this while you watch all we're doing is defining the location of the database and the name of the database so that's on our localhost because the mysql server is running on my localhost and the name of the database is serverdb and then my password in my username i defined the dialect so kind of like the version which is version 8 that i have installed and then i want to format all the log and i want to show all the log so that's a very small configuration that we're doing for the database and this is also assuming that you have mysql installed on your computer already because we're not gonna go through that so if you already have mysql installed then that should work for you you just have to change the information here to match your information and also change the version as well if you don't have version 8. and you can use postgre or whatever relational database that you want to use in this case i have mysql installed so i'm just using mysql but you can use postgre or whatever else you want as long as it's a relational database then everything should work fine so if we didn't make any mistakes at this point if we run the application everything should work so we're gonna go ahead and do that so i'm gonna go ahead and start the application and if we did everything right then we shouldn't have any errors or anything like that so you can click on this button here or you can go into the main class right click it and then just go to run server application and that should start the application so let's see what happens all right the application started with no errors and we can also see the logs that our table has been created so to verify this let's go ahead and open mysql workbench you can use any client you want but i'm going to be using the workbench for mysql so i'm just going to go ahead and open that and you can see that i created this server db so make sure this is created and i'm going to expand this and refresh this by just clicking on this refresh icon and inside of here you can see that i have this server table created so that means that everything went well and we didn't get any errors and we can click on this little gear here so we can describe the table so you can see that we have our id it's a primary key it's not null and you can see that we have the ip address it's a unique key so you can see that this is checked off so our constraint is there you can see all the other fields that we have in the class they have been mapped to this table so we can go ahead and click on this little calendar icon to bring everything up and if i zoom in a little bit so that you can see what we did so we run this query and you can see that we have all the information that we added when the application ran then we save all this data so our data is there application is running so we can go ahead and test it in a browser or any http client so i'm gonna go ahead and minimize that and i'm gonna open postman because i'm gonna be using postman and i'm gonna open a new tab and here i want to send a request so i'm gonna do http and that's 8080 and i don't need to go to api greetings i want to go to server and i want to go to list okay so if we go back to the application for one second and let's minimize this and go to the resource open the server resource make some room so we're gonna go to slash server slash list so this is gonna go into the database and grab the first 30 items that we have in that table and we only have like four so we should get everything that we have so let's go back to postman and go ahead and run this also remember the method is get because we don't want to send any other method to this url it's supposed to be get so let's go ahead and send this request and you can see i got a very beautiful response i got the timestamp the status code the status the message and you can see that and the data for the key we have an object and that object contains a servers which is an array and you can see that we have all of the information here nicely printed out so we know that our application is running smoothly so let's test the other functionalities so i'm going to duplicate this and we want to go to get and we have id 1 2 3 4. so we can grab any one of those so i'm going to do forward slash and then pass let's say 2 and this is also a get request so this is going to return one server where the id is 2. so let's go ahead and send this request you can see that i got a beautiful response again and we got the server with id2 inside of our data and the server is an object so let's go ahead and test the save so i'm going to copy this object and open a new tab or duplicate that one and go to the body that's going to be raw and we need json and it's going to be a post request and it's gonna go to server.save and we want to paste this in there i'm gonna make this a little bigger we don't need to send the id so i'm gonna go ahead and delete the id and let's change this to let's say 195. and let's say this is ubuntu and let's say this is 32 gig and let's say this is not a dell tower let's say this is a lenovo so lenovo and we can change the image let's say we're going to pass in the well we don't even need to put the image because it's going to be added on the fly so if we send this request this server should be created so let's go ahead and send this request and you can see we got the 201 created this server is created you can see that we get the image by default which is the server three and then everything looks good so now if we go back to the get list everything again we should see that one at the bottom as you can see it's right here so everything seems to be working so one thing i want to test is the image url so this image rail here so i'm going to go ahead and click on it and it's going to take me to this new tab where i can actually send the request so let's go ahead and send this request and make sure this is working all right so we got an error so server internal server error so let's take a look at the back end and let's see what we have in the run scroll up go to the bottom and let's see here so we have a mistake as you can see here in our string so it tries to go to this location but we need a forward slash here or a backslash instance windows and so user home so after the user home we need a four slash here so that was the mistake so i'm gonna put a four slash here and i'm gonna restart the application and i'm gonna open the run console make sure this looks good all right so everything looks good so let's go back to postman again and let's go ahead and send this request and you can see that we get the image so you can see the image is right here and i can change this to let's say one send it get a different image change it to two send it get a different image now the other thing that i want to test is the ping so i'm going to duplicate this tab one more time and go to ping and then we need to pass in the ip address so let's go back to the list and so let's resend this get request so that we can get fresh data and let's say i'm gonna see if i can paint that one because i think it's gonna be a success i think this is an actual server or computer on my network and then here i'm going to pass in the ip address this is also a get request so make sure the method on the request is get and let's go ahead and send this request so i'm going to go ahead and send it and you can see it says bank success and then we get the server back and we can see the status is up so even if the status was down after we ping it successfully the server set is going to be up so let's see if we can try one that doesn't work so let's scroll down i think that last one should give us an error because i don't think i have this ip address so i'm going to change this ip address and send the request again and again you can see ping fail and then we get the server back and you can see the status is server down so everything seems to be working properly and you can go ahead and test all the other functionalities everything should be working as expected use your postman or whatever your http client is and you can send requests and everything should work as expected so at this point the backend is ready and up and running so we can go ahead and start working on the front end and again if you have any question just reach out to me i'll be happy to help you i really went through this really fast so if you have questions or something is not clear so make sure you reach out to me and i'll be happy to help we might have to come back to this if we see that something is not the way that we want it to be but at this point i'm satisfied with this work and from this point on we're gonna be working on the front end and like i mentioned before for the front end we're gonna be using angular but i might do another video where i show you how to do the same thing but using react.js instead because the same backend can be used with any framework or even vanilla javascript you can use the fetch to send requests to the backend so the front is going to be angular and that's what we're going to be working on what we're gonna need for the front end is node.js so if you go to nodejs.org you should be presented with a page like this and you can either download either version and the reason we need node.js is because we need the node package manager so that we can install the angular cli so i have the angular cli open and you can see the command right here it's npm i for install and then at angular cli and the angular cli is the command line interface and you can use it to manage angular applications so create application deploy build all the fancy stuff that you can do now with command line interface so go ahead and download any versions of node.js that you see on here doesn't really matter because we're not really going to be using node.js per se and then once you have node.js installed go ahead and install the angular cli by just running this command and after you do that you should be ready to go i mean assuming you don't get no errors or anything so now i'm gonna create the angular application so i'm gonna open my terminal and i'm gonna bring it up here so this is my terminal you can use any terminal you want doesn't really matter and we're going to create the angular application and to do this we're going to do ng so after you install the angular cli you have access to this command which is ng so this is like how you invoke the angular cli and then you can pass in commands and it's just gonna do things for you you know help you manage your application create the application run it deploy it etc and to create an application all you have to do is ng new and then you pass in the name of the application so in this case i'm gonna call it server app the back end is called server the front end is called server app just to make the difference between the back and the front and then i'm going to press enter and i think i have to answer some questions here i'm going to say yes on that would you like to add angular routing so this is a single page application and by this i mean we're not going to have any different route it's always going to be one page so i'm going to say enter this for no and it's asking if i want css sas or scss for my styling i'm going to stick with css and it's going to go ahead and create the application for me as you can see it's installing all the packages that i want so i'm gonna let this finish and then i'm gonna come back everything is installed so i'm gonna go ahead and navigate to that folder so server app and i'm gonna clear the screen and what i wanna do is open this with visual studio code so i'm gonna type code dot to specify this folder and then visual studio code is gonna open in that specific folder so i'm gonna press enter and it open in my other screen so i'm just gonna go ahead and grab it over and open it up so you should be presented with a screen like this and all the files and folders are gonna be on your left on your panel here as you can see everything is populated everything has been created so there's one thing i wanna say before i actually start doing anything so for the front end i'm gonna be using a more advanced technique and i'm gonna take a reactive approach so we're not gonna have a procedural way of doing things like when you define functions and things like that and then you call the function and then you wait for a response well per se we're gonna kind of do that but it's gonna be more reactive than anything else and i'm gonna go ahead and show you what that means in a second and i'm gonna show you the example where we have a procedural way and when we have a reactive way and you're gonna see the difference and also see the benefits of using the reactive waste it's gonna be a little bit more advanced but there's a lot of benefits for using a reactive approach in angular then using a procedural approach if we inspect the package.json for example and we scroll down a little bit and all the dependencies you're gonna see that we have rxjs here so by default the angular application that you get from using the angular cli it comes bundled with the arcgis library which means that whoever created this framework they intended for the developers to use this library and their development and we're really going to be making extensive use of this library so that we can create the reactive approach that we want to do in this application and you're going to see how this is going to be different from what you've been seeing and you can also see the benefits for creating your angular application that way so i don't want to say it's better than the procedural approach because you know they all have their benefits and disadvantages but that's just gonna give you a different perspective when you're building your angular application so really pay attention to what i'm gonna be doing here and if you have any questions of course reach out to me i'll be glad to help you so let's go ahead and get started so the first thing i want to do is going to go ahead and close this and expand the source folder go inside the app folder and in this folder i want to create another folder so i'm going to do a new folder and then i'm going to name it enum so i'm going to put all of the enums that i'm going to be creating inside of this folder so i'm going to right click and do a new file and i'm going to call this status.enum.ts so i'm going to create the studies that we created in the backend so that we can map it in the front end right here so i'm gonna do export and this is an enum i'm gonna say status and open and close curly braces and i'm gonna press ctrl b so that i can close the panel and for the enum i want the all so you remember in the beginning when i gave you the demo you saw that you can filter everything by all we don't have that in the backend but we do have it in the front end because i want to give the user the ability to select all and then view all the statuses for all the servers and i'm going to set this equal to a string that's gonna be the same thing so that's gonna be the first enum the second one is going to be server up so exactly what we have in the back end so i'm gonna do server up and i'm gonna go ahead and set it equal to the same string so i'm gonna do server underscore up and then lastly we have server down so i'm going to do server underscore down again set it equal to the same string so this is going to represent the status that we're going to be working with for the servers so that's one enum that i'm gonna need and then i'm gonna go back to the app folder so in the same app folder i'm gonna create a new folder and i'm gonna call it interface and inside of this interface folder i want to create the server so that i can map that server as well so i'm going to do new file and then i'm going to do server.ts and i'm going to export interface and this is the server put in close curly braces and remember we have an id which is a number we're also going to have an ip address so ip address which is a string and then we have the name which is also string and then we have the memory so memory also another string and we have the type so type also another string the image url so image url also another string and then lastly we had the status so that's the status and we're going to give it a type of status so the same status that we just defined as the enum that's going to be the status and you can see that it's auto imported up here so this is the interface for the server so whenever we are mapping everything to the front end so when we make a request to the backend we get the response to the front end so this application will be able to map the servers or the list of the servers into this interface right here so that is what i need to do for this server now i'm going to close this and then i'm going to go back to the enum i'm going to create another file and i'm going to call this file data state dot enum dot ts so this is going to represent the state of the application and this is probably not going to be making a lot of sense right now but this is going to make sense later so just bear with me so what i want to do again is just export this so i'm going to say export enum and this is going to be the data state so this is going to represent the data state of the application and the state that i want to have they are loading and i'm going to set it equal to another string that's exactly the same thing so we're going to say loading so this is going to represent the application when it's in loading state i'm going to press ctrl b again to collapse this panel and then i want the loaded state so i'm going to say loaded and set this equal to the same string and then lastly i'm going to have an error state so error and i'm also going to set it equal to the same string and the reason i'm setting these to the string is because i don't want to deal with the indices because whenever you have an enum by default typescript is going to assign an index to this so for the value for the loading it's going to be 0 and that's going to be 1 and then 2. and i don't want to deal with the indices or the numbers and i'm also going to be showing this little ui so i don't want to show 0 or 1 or 2. i want to show an actual string that makes sense to humans so i'm changing those and then you know add the value directly as the same as the item so this is going to represent the state of our data and let's go ahead and go back to the interface folder create another file and this is going to be the issue response so i'm going to say custom dash response dot yes and ctrl b again to collapse this and i'm going to do export interface custom response so remember we create this response in the backend we also need to map that in the front end so that's what i'm creating here and we have a timestamp and that is a date and we have a status code so status code which is a number and then we have the status which in this case is going to be a string and then we have the reason also string and then we have the message also another string and we have the developer message also another string and then in the back end we have a map that's going to represent the data so here i'm going to say data and then i'm going to give it a type of an object so i'm going to do open and close curly braces and inside of that data we can have either servers which is going to be an array of server so i'm going to say server array and it can also contain just one server whenever we're returning like one server so if we call the get on the backend and then we pass in the id that's going to return one server so here i can say server and also give it a type of server and i need to import those so quick fix import from our file and another thing i want to do is to make these optional because we know that we're never gonna get both of them at the same time so i'm gonna go here and put a question mark and also go here and put another question mark so this is how we tell typescript that this is optional so it's possible that we may not have this value inside of this data object i'm going to go ahead and put a semicolon and this is all we have to do for this interface so there's one last thing that i want to do and then we're going to start working on our service so instead of the interface folder i want to represent the entire state of the application so like i said we're going to take a reactive approach and this is not going to make sense later so i'm going to create another file and then i'm going to call it app dash state dot ts so this is going to represent the entire state of the application so we're going to capture the entire state of the app at any given moment inside of this state interface here so i'm going to collapse this again with control b and then i'm going to do another export interface and it's going to be the app state so app state and open and close curly braces and what i want to have in there is the data state because i want to know the state of the data and of course it's going to be of type data state so that's our enum and then we need also to grab the data so i'm going to say app data you can name this data doesn't really matter i want to make this generic so to do this i'm going to go up here and put the diamond and then pass in the type here so i'm going to pass t and then say whatever type is passed up here is the type that this data is going to be and again this didn't have to be t this can be any letter as long as you use the same letter inside of the class then that should work just fine and then lastly i want an error if we get an error and then this is going to be a string so remember we can't get the data and then get an error at the same time so we can either get an error or we get the data so what that means is that i'm going to have to make this optional so i'm going to come up here again put a question mark go down here put another question mark so these two values inside of the interface they're optional because we know that we're not going to have both of them at the same time so we can either have this or have this other one so the application state is gonna have some sort of data and whenever we're using this interface we're gonna have to pass in that type here which is gonna be the type of the application data and this application data is gonna contain all of the data of the application the data state is going to determine the state of the application so at any given moment we can call on this data state and it's going to tell us in what state the application is we can either be in the loading state and the loaded state or in the error state and since this is the data state so we know that our data is loading or it's loaded or it's an error so all this information is going to be captured inside of the application state which is going to represent like i said the entire application state at any given moment and another thing i want to do now that i'm remembering is to make this loading state so that it can make more sense so i'm going to go up here and do underscore and then do state and i'm just going to go ahead and copy this and paste it in all of them so i'm going to go here paste it go here and paste it paste it here paste it here and then paste it in that last one so loading state loaded state and then error state all right so we have the application state ready and now we can start making call to the backend and see how we can map the response to this application state which is what we're going to be using to manipulate the ui so let's go back to the folder and let's collapse this for now and i can actually close all this and inside of the app folder again so instead of the main app folder i'm going to create another folder and i'm going to call it service and by the way you can create interfaces and enum with the angular cli as well and you can also create service with the angular cli and i can quickly show you an example so i'm going to bring up my terminal and inside of the application which is where i am right now as you can see i can do ng generate or ngg for short and then i'm going to say service and i want this to go inside of the service folder that i just created so i'm gonna type service and then i'm gonna name it server so that's gonna be the server service so that's the file that we're gonna use to make hdb requests to the backend and then i'm gonna press enter i'm to click yes on that and you can see that the angular cli created two files for me the server service.ts and also the serverservice.spec.cs which is a test file so i'm going to minimize this for now and if you go inside of that folder now you can see that we have those two files so i'm going to delete the test file because we're not going to be writing tests in this course so if i open this file now you can see that the angular cli stubbed out the code for me so i'm going to collapse this again and just clean this up a little bit just move this over you don't have to do this it's just a preference that i have and inside of this class we're going to create all the functions that we need to make hdb requests and before we can make a ship request in angular we need to do some setup let's go and let me show you how you can do this so inside of the app module we need to bring in the http client module so we're going to put a comma and then do http client module and make sure this is imported on tab so it's supposed to come from an angular command http so that's the http client module so we don't need to do anything else here we're going to go ahead and collapse this again and then now we can inject the hiv client and the constructor for this class so that's similar to dependency injection well it is dependency injection so we're gonna say private i'm gonna call it http and then we're gonna give it a type of http client so i'm gonna say http client which is coming up here so now we have the http client injected inside of the server service we can use this client to make ac recall to the backend so that we can retrieve data and then map this data to our application state that we just created earlier right here this application state so let's go ahead and go back and close this so the first thing we need to do is to define a method to retrieve all of the servers so let me show you an example of what you would usually see which is the procedural approach so we can have like get servers as the function name and then it's not going to take any parameter and it's going to return on observable so observable and that's going to be of type custom response so that's the response that we created you can see that's coming from our interface and then open and close curly braces and inside of there we will return this that http and then we would access the get and then pass in the http url inside of this get method and we could do something like http colon double forward slash localhost and we're running on 8080 and you would go to forward slash server for slash list okay so that would give you the list of all of the or an array of all of the servers that we have in the backend and we also have to type this as well so i'm going to copy this and pass the type down here so that we can get rid of this error and then end this with a semicolon so this is the typical way that you would actually make requests to the back end and that's more of a procedural approach which is totally fine there's nothing wrong with this but i just want to show you a different way of doing things and to do this i'm going to be taking a more reactive approach so i'm going to go ahead and just get rid of that all together and what i want to do is to define an observable and i'm just going to call it servers so when you're defining observables it's a good practice to put data sign in the end and that's how you denote an observable so the server is going to be observable it's going to return a list of servers and then i'm going to set it equal to this that http that get of course we're going to type it so we're going to say this is of type custom response and then we're going gonna pass in the url so here i'm gonna say let's say i'm gonna define some variable in this class so i'm gonna use template literal and i'm gonna say this that api url and let's go ahead and define this right now quick fix declare so this is gonna be some kind of string so we can leave it like this for now and while we're here let's just make this private and read only and then declare it just like that let's just set it equal to the string so that we don't get any errors and then we want to go to forward slash server forward slash list okay so this is going to return the list of all the servers and you can see i'm directly assigning this variable to this observable which in turn make this variable unobservable as well and then i'm gonna do that and then call the pipe operator and inside of the pipe operator i want to do two things so i'm gonna go ahead and log what we got so i'm gonna call the tap which is another operator and then use the console.log so we're gonna lock the response onto the console and then i can use the catch error so i'm gonna say catch air which is another operator and then i can call a method so let's say this handle airs okay so we don't have this method yet and we're gonna go ahead and create it right now so i'm gonna click on here click fix uh this is a method so i'm gonna declare it at the bottom ah it's on top so i'm just gonna cut it from up here and go down and then paste it so handle error let's just remove all this junk right here and this is going to return an observable of never and we can just return this guy right here so we're going to say return and we're going to call the throw air instead so throw air and you can see it's coming from rxjs as well and i can just pass this string for now remove all this and we need to make this unobservable so let's go here and do observable and everything looks good so this is the handle error function we also have to import the catch error quick fix this is not what i want these are coming from rxjs so i'm gonna have to do this manually so let's go and scroll up and the throw air is coming from rxjs and i'm gonna go ahead and duplicate this line and we want things to come from arcgis forward slash operator so operators right here and what we're looking for is the tab so i'm gonna copy this and paste it here and also the catch error and then paste it here all right so now all of our errors should go away so this is how i'm gonna define this observable we're gonna go ahead and make the call pipe the response we're gonna log to the console so that we can see it and then we're gonna catch any errors that's going to be processed by this method right here so this is our observable and i see that it's giving me the type of any and i don't want that so let's go ahead and just copy this i can actually copy all this and i'm just going to go ahead and cast it so i'm going to put it in front of this and change this to a custom http response and then put this on a new line and since we're casting all of this so we need to enclose this in the diamond so i'm going to do oops uh open and close and then copy all this or cut it rather and then paste it in here so now if i hover over servers you're going to see that it's returning unobservable of type custom html response so this is the observable that we're going to be using in the component so that we can retrieve a list of all the servers so now i can just copy this and then go down and then paste it and this is going to be the save i'm going to say save so that's saving the server all of this look good but the only difference is we're gonna go to save and this is gonna be a post instead of a get so we're gonna say post and now we need to pass in the request body because it's a post request so we're gonna make this observable take the server so we're gonna go up here open and close parenthesis and we're gonna say this is gonna take a server which is gonna be of type server and then put the error function here so i don't know if you guys are familiar with uh error function but these are technically arrow functions and then here we can pass in this body so we're gonna say server and everything else is gonna be the same the only difference is this observable takes the parameter which is the server which is of type server and we passed it here as the request body whenever we call server.save this is gonna be the body of the request and then i'm gonna go ahead and copy this again gonna go down paste it this is gonna be the ping so i'm gonna change this to ping and it's gonna take the ip address so i'm gonna say ip address and this time this is gonna be a string so i'm gonna pass in the string change the method to a get and we don't need the body anymore and this is gonna go to ping so we're gonna pass in ping and then we need to pass in the ip address as part of the url so we're going to do the same thing again since we're using template literal and then pass in the ip address and i'm going to copy this one more time scroll down paste it this is going to be the delete so i'm going to say delete and we need the server id so server id which in this case is going to be your number and pass in the server id as part of the url as well and this is going to go to delete so change the ping to the late and this is the delete request all right so let's go ahead and work on this method down there the first thing i want to do is to make it private because it's supposed to only be used inside of this class and then console.log that so i'm going to say console.log and then pass in the error let's see what this is what is this called uh let's call this air and this is going to be of type http error response so we have to we can type this properly and then i'm going to copy this and then paste it so this is going to be for our debugging purposes whenever we're debugging this application or running it so that we can see the error in the console if something happens and i'm going to remove this extra space here and we can pass in any message that we want here so i'm going to say an error occurred for example and then pass in the status code so i'm going to under dash error code and then pass in the error code so that'll assign open and close curly braces error that there's supposed to be a status on this so here that status so we can actually make this a lot more refined because right now i'm not really using all the stuff that i'm getting from the back end because i don't really want to focus on this too much and the last function that we need inside of this class is the filter function so i'm going to go ahead and copy this delete again and i'm going to put it before the delete and we're going to call this filter so filter what this is going to take is the status so we're going to say status so the status by which the user want to filter the servers by so this is going to be of type status so that's coming from our enum and we also need the response so whatever the current response is or whatever the current data is we need to access that and i'm going to give this the type of custom response and we're not going to be calling the backend to filter the notes because why would we do that if we already have everything right here and the front end already so we're not going to do this line right here and instead we're going to create a new observable because we have to make this return observable so i'm going to say new observable and we can also give it the type so that's going to be of type custom http response and then open and close parenthesis and what we need is the subscriber so we're gonna give this any name that we want usually you would see that it's called subscriber and then call the callback function and the first thing i want to do is to maybe like console.log that so that we can see what we get so i'm going to console.log the response and then the only thing i have to do is to call the subscriber and then call the next function on this so the next function of method it's just gonna emit something to do observable so whoever is subscribed to this observable they would get this new value in that case since we said that it's gonna be a customization response then whatever we have to uh next on here it's supposed to be the custom http response so i'm going to open and close on parentheses and what we have to do is to check to see what the status is so if the status that we got from the function if this is all so we're going to put three equal signs and then check the status that all we're going to put a question mark so if this is the case we can just return the response because we don't need to filter anything because the user choose all so that means they want to see all the servers we don't need to do any filtering or anything like that so i'm going to create a new object and i'm going to get everything that i already got from the response so using the spread operator so i'm going to do response and the only thing that i want to override on the response is the message so i'm going to say message and then we want to set this to some message and if you remember from the demo we pass in something like servers filtered by and then we can pass in the status so dallas line open and close and then whatever status that they pass which and this is gonna be all and then we're gonna say status and i'm going to scroll over a little bit and here i'm going to put a colon so in case this is not the case so in case the status is not all then we need to filter everything and then return a different object to the users in the first case where everything is all we're returning this object so everything that we already got so the same data that we got in the response and we're overriding just a message so if this is not the case then we need to return a different object so i'm gonna put open and close curly braces again i want to spread everything in the response again so i'm gonna say response and i need to override the message again so the message is gonna be similar we're gonna say you know server have been filtered by whatever status and the way that i'm gonna do this is by checking to see after i filter all of these servers do i actually have anything so if i filter the servers and it's zero so let's say user choose servers down and currently we don't have any servers down so i have to say something like there's no server because it wouldn't make sense to say you know server filtered by down status because there's no servers so i'm gonna go inside of the response and inside of the data and i want to access all the servers and then i can call the filter because this is an array and i want to say for every server that i get call the callback function and then check to see if the server that status equal to the actual status so status so that's the status that we're getting from the function from up here and then i can check to see if i have anything in this array so i can call the length and then check to see if it's greater than zero so greater than zero and then put a question mark so that is similar to what we're doing here so we're saying if when we filter all the servers which is what we're doing in here when we say response data servers and then filter all the servers by that status so whatever status we got if the length of this array after we filter it if it's bigger than zero then our message is going to be something so i can put string literal and then i'm gonna pass in the message and i'm gonna put this on a new line so you guys can see it so i'm gonna copy all this line and then paste it here and then i'm going to say server filtered by whatever the status is and then status so there's another thing if i go inside of this enum you can see that the set is going to be like server underscore up and then server underscore down so i don't want to have that here i want to have something like server up and server down so i can do the same thing again inside of this string literal so i'm going to put this on a new line and instead of saying server is filtered by whatever the status is so that's going to be status underscore up status and i don't want that so i can check to see if this is the status up so i can do status that server up and then put a question mark again so if this is the case then the string is going to be server up so i get rid of the underscore otherwise it's going to be a different string so i'm going to do server down because i only have two different options so the first case of all will be cut here and in here i know it can only be server up or server down so remember we're still inside of this first one so here now i can put another column and then return another string so that's the case where we don't have any servers after we filter everything so now we can say something like no servers of and then pass the status again status and then we can say something like found this is gonna be our message and it's gonna go off the screen i'm gonna put this again on a new line so that you guys can see it and then the last thing i wanna override is the data because that's the actual data that we have to return so i'm going to say data and remember this is an object so i'm going to put open and close curly braces and also let me get rid of this error because we don't need this question mark here and now it's telling us that this can be undefined and i'm going to show you how to fix this in a minute and for the data we're pretty much going to do just this the key again is going to be servers as you can see everything is coming up because we typed everything and then we're going to set it equal to this guy right here so we're going to just copy this and then paste it here so this can be a little bit confusing so make sure you really go over this multiple time because i understand that this can be a lot to take in all of a sudden we have two areas here and i'm going to tell you why this is telling us that this can be possibly undefined and that's because we have a configuration in this application and i'm going to show you how to manage this properly and remember we're still inside of the next which is going to either return this object or this other object to the color of this observable but after we call next on the subscriber so that we can emit something to whoever is subscribing to the observable we also have to complete the observable and this is how we signal that we have finished with what we were doing so we're going to call this subscriber again and then call complete so that's how we tell the subscribers okay we're done emitting whatever we're emitting we have completed as unobservable and again like i said this is quite a lot and there are many different ways we can do this we can use if statements instead we can use switch but i found this to be a little bit more interesting and i really have no idea how to put this uh you know in terms of lines so that you can really see it clearly uh if i put it on one line it's gonna go off the screen so make sure you can copy this and paste it somewhere else just take a look at it put it on one line and check everything make sure you understand what's going on here but this entire block is just for the message and just so you guys understand i'm gonna go over it one more time so what we're doing is trying to filter all the servers by specific status so what we're getting in terms of what parameters this observable is taking is the status they want to filter by in the data so the entire http response and what we're doing here is we're creating this new observable okay so you can see that this is a new observable we give it a type and then for the callback function which takes a subscriber so we're naming this subscriber we're gonna either return this object so you can see the beginning and the closing all the way down here and what we're doing is we're console logging the response so now we can see what we have and then we call next which is how we emit a new value to whoever is subscribed to this observable and then the first thing we do for the object that we're gonna return we're gonna check to see if the status is all which is what we're doing here if this is the case then we're going to return this response so this is the object that we're going to return all that so we're going to spread everything that we already have in the response and override the message property inside of the response object or the custom http response object up here otherwise which means if the status is not all then we have to filter the servers so we're gonna put this colon for the or because we have a question mark here and then we're gonna spread everything in the response again and we're gonna try to override the message and the data that we have to filter so the message is gonna be we're gonna filter all the servers which is what's happening here what is highlighted and if the length of this array after we filter everything because when you call the filter it's gonna filter the array based on this condition so if after we check we see that the length of the array is greater than zero then we're gonna pass in this as the message which is gonna be all that and here we're doing something similar again inside of the message so we're gonna say server filtered by and then the status which is going to be all this is going to be either server up or server down depending on the status so if the status that they pass is server up the string is going to be server up so it's going to be servers filtered by server up status otherwise it's going to be server down so that is just for the message but in case that we didn't find any server after we filter the server by the status then the message is going to be no servers of whatever the status is found so this is all for the message and then remember the most important thing is the data so that's the servers that we have to filter and return to the user and that's what we're doing here so we're going to say for the data which is an object how do we know it's an object if we go inside of here the data remember it's an object and we just have to filter these servers so inside of here we're gonna see for the servers we're just gonna get the response so whatever we got from the caller of this function grab the data which is gonna be this data and then access the servers you can see here for the servers we're just going to go ahead and filter everything by whatever status that they pass up here by just using the same filter array method and now for this error so if i overrun this it say this can be possibly undefined and that's because we have some configuration inside of the typescript configuration file so i'm going to show you where this is so if you scroll down and you go inside of the ts config and collapse this this streak true it's for a bunch of configuration that we're turning through here and i can show you real quick if i go ahead and turn this to false and go back and just wait for a couple seconds you can see that the error is gone but you shouldn't do this because this is important for good development you don't want to turn this entire thing off and i'm going to go ahead and show you exactly what this is doing so let's go back to the browser and i have the page for typescript link and you can see the strict for the configuration it's going to turn all these things on okay so it's going to always check for strict strict null checks so it's really enforcing a lot of things for us by just turning this to true so for now i'm gonna turn it to false which is not recommended and then i'm gonna go through these and see which one that i wanna turn on and which one that i want to turn off because you really don't want to turn all of these off because it's really good for your development so that people don't make mistake and make things undefined and all and they're not supposed to but i don't want to deal with this right now so i'll go ahead and you know turn on the ones that i want to be turned on and then turn off the ones that i don't want so let's go back to the code and we're going to keep it at false for now and then go back to the application so i hope that makes sense and again if something is not clear go ahead and reach out to me i'll be happy to help you and also one last thing you can see that we're also piping all of this the same way that we're doing for the http call that we're making and remember these hdb functions they return an observable and you can go inside of them and you're going to see that it's returning an observable of whatever type that you pass it so these are returning observables so the same way we are manually creating this observable so we can call the pipe on this function as well because it's technically unobservable so if while we're doing this operation something goes wrong then we'll also catch it in this exception here so that's all we'll need to do for this server service and i'm going to show you how we're going to use all these in the component and then have our application state at any given time in the application because the application state is going to determine which part of the ui that the user can see at any given moment and i'm going to say this one more time this is a lot to take in so make sure you you know pause the video slow it down or do whatever you need to do and make sure you understand what this is doing our service is now ready so we can start making use of this service and the component let me make sure i have the air so it's gonna throw an error okay so i just wanted to make sure that i actually put some implementation for this function and also you can make this function a lot more robust like you can put if statements and check for whatever you want to check but in my case i'm just going to throw you know this code right here and then i'm going to show the status but you can also access the message like the developer message that we set up in the backend it should be inside of this guy right here but in this case i'm just gonna throw this string right here which is just gonna be a simple string so let's go back i'm gonna close this first and then go back to the component so i'm gonna collapse this interface and service for now and go back into the app component so this is the main component of our application and i'm also going to go ahead and delete the spec file because i'm not going to use it with the recycle bin what i want to do is to clean this html file delete and instead of the app component we're going to start working on our application in here so the first thing i want to have is a constructor so i'm going to define a constructor so that i can do dependency injection because we need to bring in the service that we just created and this is going to be the server service so i'm going to call it server service and it's going to be of type server service so server service so in the constructor for this class so this app component class i'm going to collapse this for more room so instead of this class we have the server service so that means we can use all the functions that we just defined in the server service and then uh get the data that we need so i'm gonna come down here and i need to implement a lifecycle hook called ng on init so i'm gonna do ng on init and this is not gonna take anything it's gonna also return void and open and close curly braces and for this to work we need to actually implement an interface i believe so implement on init so because we're implementing this on init then we're obligated to define this method right here so what this means is that whenever this component is done initializing it's going to call this ng on init and that's gonna fire any code that we put inside of this function and that's exactly what we're looking for because we want the code to execute once this component is initialized so remember i said that we're gonna capture the entire state of the application and that's going to be a variable that i'm going to call app state and it's going to be an observable so i'm going to put the data sign at the end and then i'm going to give it a type of observable and that's going to be an observable of type app state so we're going to call the app state interface that would define remember this is a generic so we need to pass it the type of data that we're gonna have in the state so the type of data is gonna be the custom response so i'm gonna say custom response so also from our interface and that's going to be our type so the entire application state is going to be inside of this observable or this variable and the type of it is an observable and then we pass in the type for that observable which is the entire application state and the data that we're going to manage is the custom http response so remember the app state is generic so we have to pass the type of data we want in the application state so for this state right there and then we pass in the custom hd response which is going to contain all the data of the application at any given moment hopefully this is connecting so what i want to do when the application initialize i want to set the state of the application so i'm going to call the application state and then set it equal to the service so server service and then i want to call the servers because this is going to return a list of all the servers in the application and then what i want to do is to pipe this so i'm going to call the pipe operator i want to map any response that i get so i'm going to call the map i'm going to say whenever you get a response from the server right i want to execute a callback function and i'm going to put open and close curly braces here because i want to have multiple lines so if we have a response we want to return an object which is going to be of type application state because remember we're setting the application state here so whatever we put inside of this object it has to be of this type right here okay so let me scroll up a little bit so what i want to do is to set the data state so i'm going to say data state so the data state is going to be the data state so i'm going to say data state and then we want the loaded state so that's going to be loaded because at this point we know that we get a response from the server so our data is loaded and then we need to set the app data so we're going to say app data and this is going to be the response that we get so we're going to say response and you can see this is not complaining because this is a valid object to return here because it matches the description of the type that we set up here so the application state which is unobservable we already and unobservable because the server is unobservable and then we're piping the response and map it to this object which is also the same type of this object that we define up here this is only going to happen whenever we get the response so when the application is done initializing then it calls this ng on in it then it's going to say all right i need to subscribe this observable and this observable is going to make an hdp request so that means we're not going to have this data right away because we have to wait because it's on hdb request which means that we need to give this observable something to begin with and we're going to use another operator called start with you can see it coming up here and then we can give it another object to return while we wait for the data to come back so what i'm going to do is to just copy all this and then paste it in here all right so what i'm doing here is saying okay so we're going to subscribe to this observable which is going to make an http request that we as the developer we know that this is going to take some time so while this is going on so while we're making the request to the back end we're going to return this object to this observable and at this point our data is not loaded so our data is loading so we're going to select the loading state and also remember i made the data optional so if you go back to the application state the app data is optional so that means we don't have to pass it because we know that at this point in the application while we're waiting for the http request to complete we don't have any data yet you could do something like this you could say no that would work as well but i can just omit it all together because it's optional i don't have to pass it so i'm just going to say okay at this point my application state the for the data state it's loading and then one last thing i need to do is to catch any errors that occurs in the application and for this i'm going to use the catch error again so i'm going to do catch air which is coming also from the operators and this is going to take the error so i'm going to say this is going to be the error and we know that this is going to be a string so if i go back real quick to the service i'm just going to click here to go to the service remember whenever we get an error so for any of these functions whenever we get an error which is gonna go to the catch air it's gonna call this function and pass the error to it which is what we're catching down there and all we're doing is we're throwing the error by just sending this string okay so that's a simple string we could send an object we could send something really complex but in my case i'm just sending this simple string so this string is going to be the air that we're catching here which is why i'm giving it the type of string because i know for sure that it's going to be a string every single time and then what i want to do is to just call the callback function and what i want to do here is to return another observable so i'm going to do return of which is another operator from ihs that you can use to create an observable on the fly and in here i'm going to pass in another object remember every object that we pass it has to be of this type so the type that we define up here which is what this is expecting because we set this equal to this entire thing so whatever we put inside of this guy it has to match this data type right here so i can just copy the same object in here and then go down here and then paste it but this time it's not going to be loaded it's going to be the error state so i'm going to select the error state because we get an error and then i can pass the error as well so you can do something like this so air is going to become air because remember if we go back one more time into the app state we call this property air so another thing we can do since we named this error and this is also air as well we can just pass in one of them because they have the same name so javascript will be able to do the work and say like okay for the error it's gonna be this area right here so we can just keep it that way and you can see now everything looks good we don't have any errors in the application because we're setting our state correctly so we can subscribe to this observable and at any given moment it's either gonna say all right we get some data or it's gonna take the data is loaded or we're gonna get an error and the way we're gonna subscribe to this observable is in the ui by using the async pipe so that's gonna make everything really easy for us whenever the application initialized it's gonna go through this and then it's gonna say all right i don't have the response yet so i'm just gonna start with this so we can say hey application is in loading state and then once we get some data then it's gonna return this state or if we get an error for some reason then we know we're going to get this error state and then we're going to get an error message that we can show to the user so this is a reactive approach instead of you know subscribing here and the component and things like that so that's another way you can write your angular code and there's really a lot of benefits for writing your code this way so before i continue with the other functions that i need for this frontend application i want to show you what this application state looks like so you can have a better understanding of what we're doing here so i'm gonna see if i can spin up the back end and then run the front end and then see if i can show you what this application state looks like you know to help you visualize things a little better so i'm gonna go ahead and format this a little bit and i need to go inside of the service so let's go inside of the service we need to set this url so that's going to be http colon double forward slash localhost and this is running on port 8080 and this is going to be the base url so just the domain and then the port because we're going to you know slash server slash list slash server etc so we could also make this slash server as the base url but that should work fine so we have the url in so that's going to be our in url so now we just have to run the backend so let's open the backend application and there's one thing i want to do in the backend application so if we try to run this back in and try to access it with the angular application we're going to get a course error because the domains are not the same and if you don't know what the course area is you can go ahead and google that but this is something you're gonna encounter when you have two applications running and you want them to communicate through the browser and they're not on the same domain so there's something that is set up in a browser for security purposes that's going to stop this from happening unless the backend server explicitly specified that this front-end application can access it then the browser is going to give you this course error so i'm going to go to the main application class because i need to define a bean and i'm just going to copy and paste it because every time it's gonna be the same code anyway so i'm just gonna copy it from my screen and then just go and paste it anywhere here i'm just gonna paste it below this method right there all right so everything is imported and everything looks good so this is just a course configuration i'm just saying hey allow this domain allow these headers and things like that and you can take a look at this if you want but i usually have this code somewhere and whenever i'm building the backend application i just add this bean just to make sure that i don't have any coarse air and you can see that i have 4 200 here for my local host in 3000 that's because sometimes i'm working with angular applications and sometimes i'm working with react.js application in the front end so i make sure i include you know the 3000 which is the default port on localhost when you're working with react.js application so that's all we have to do for the backend and i'm just going to go ahead and run this we shouldn't have any problem we should have those servers in the database so we will have something to show as part of our data so the backend is up and running as you can see here everything is successful so now let's go back to the front application all right and everything looks good and let's go back to the component and everything looks good so what we need to do is to subscribe to this observable and then read the data in the ui right there so in the html template so what i'm gonna do is i'm gonna add a div so i'm gonna say div press space and then i'm gonna put double curly braces and inside of those what i'm going to do is i'm going to subscribe to the observable that is the app state so i'm going to say abstain with the dollar sign and then we're going to use the async pipe so i'm going to do a sync and then we also need to show this data in json format so i'm going to add another pipe that is the json pipe so what this is going to do is with the async pipe we're going to subscribe to this observable and then whenever we get the data we're going to display it in json format as you can see here so i'm going to go ahead and bring the browser and minimize this as well and we want to go to localhost 4200 so i already have it copied so you can see 4200 and let's press enter and you can see that was really fast so you can see the data is right there the data state is loaded and we have the app data which is the actual data that we want to show and then we have our custom http response so all of this information is the http response metadata so the timestamp the status code and the message and then also we have the data so you can see the data is right there which is an object that contains an array of server which is all of this as you can see here that i highlighted so i'm going to go ahead and refresh this one more time and it's really fast you can't really see when it says the data is in loading state but that's something that actually happens and let's see if we can simulate this for a second so i'm gonna go back to the back end and see if i can add a delay just so we can see the different states of the application so i'm back in the back end and i'm gonna minimize this for now go inside of the resource so this is the url that we're calling and inside of this method i can put a delay i can do time let's do time unit and then we can do seconds and then we're going to say sleep for let's say we're gonna make this sleep for three seconds and we need to add an exception to this add the exception we can remove this later that is just so i can show you the different states of the friend application so let's go ahead and restart and we're gonna let this come up okay everything looks good so i'm going to minimize this again and now watch the ui and see the different states of the application so i'm going to refresh you can see that we're in loading state and after three seconds we get the data so now we're in the loaded state and of course if we had an error it would be in the error state and we'll get the error message as well so you can see how powerful using the reactive approach can be and this is the approach that we're going to take to build the entire application the next thing i want to do is to add the ui because obviously we don't want to keep looking at the data this way so i'm going to go ahead and add all the html markup that we need for the front end and i'm going gonna walk you through it it should be pretty straightforward and again my guess is you guys already know html or at least you know the basics nothing is really gonna confuse you so i'm gonna go ahead and put in the ui and then we're gonna walk through it a little bit and then after that we're gonna keep working on our function in the component so i went ahead and edit all of the ui that we needed for this application and i'm going to give you a quick walkthrough of what i did so i'm going to go back to visual studio code and this is the app component and by the way i'm using bootstrap so everything should be pretty straightforward if you're familiar with bootstrap i have the three buttons on top so the button to print the report the button to add a new server which is gonna point to a modal so a little pop-up window and then we have the drop down to select the filters and then down below i have a simple table and i'm just gonna show all the servers that we have in this table right there and then a little bit down i have the modal so the add server model so this is what the button was pointing to so whenever we click the button then it's gonna open this little pop-up window and then we can add in a new server if we want to and another thing i want to point out that i'm going to be using for the ui i'm going to scroll down and show you so this ng container is coming from angular and it's not a typical html tag so this ng container if you guys are familiar with react.js it's really a react fragment which means that we're gonna have this in the ui as developer for us to work with but it's not gonna create any markup in the actual html after the code is rendered and that's what i'm gonna be using so that i can show different pieces of ui depending on the state of the application so this ng container is going to allow us to do this so you can see that i'm putting everything inside of the ng container and then for this ng container that is highlighted i'm gonna show the spinning so this is gonna be whenever the application is in loading state and then whenever the application is ready i'm gonna be showing this one which contains an entire table and i'm gonna collapse this and i'm gonna show you the last one so this one this other ng container which is just a fragment of html it's gonna contain the area which we're gonna show in case there's an error and since i'm using bootstrap so i have to do some import so in the index.html i added the javascript that i need for bootstrap along with the css and some icon here with font awesome and then inside of the style.css i added the well i'm adding the font awesome again so i'm going to delete one of those and then i have the bootstrap cdn and then i have some custom style that i put in for the ui so all this scope is going to be available and you know this is not a ui core so it's not a css html this is more on the back inside and the front inside with angular so we're not going to spend too much time on the ui like html and css stuff so just make sure you grab all the code and then i'm going to show you how we're going to make this work how we're going to show different pieces of ui depending on the state of the application as you can see right now we're showing everything we're showing the loading state by showing the spinner we're showing the data and then we're showing the error at the same time so all we have to do is to switch on these different states and then show different pieces of ui to the user so we're gonna go ahead and get started so let's go back to vs code and you can see that i commented this line out so we're not gonna be using this anymore and what i want to do is to access the data so all the data that we need in the application is inside of this app state right here so this contains the entire state of the application depending on the data state that we have if the data is loaded then everything is in there if we get an error then we will show the last piece at the bottom so everything we need is inside of this guy right here so we just have to subscribe to this observable and then manage the ui depending on the state of the application you can already see how this is going to be pretty easy so i'm going to go ahead and scroll down in this ng container this first one it wraps all the other ones so if i collapse this just so you can see you can see that inside of this ng container that's where i have everything that's where i have the area that's why i have the table that's where i have the loading as well so this has to wrap all the other ng container that you want to show so inside of this ngcontainer what i want to do is to check for the state so i'm going to check with an if statement so i'm going to do ng if so if we have any data i'm going to set this equal to so i'm gonna say the app state so we're gonna access the app state with the dollar sign and then we're gonna add the async pipe remember this is how we subscribe to an observable whenever we're in the ui and i wanna give this another name as well so i'm gonna put it in parenthesis and then use the s so that i can give it a different name and then i'm going to call it abstain just so i can get rid of this dollar sign at the very end because i don't want to keep using this variable name all the way in the template so i'm subscribing to this observable by using the async pipe and then i'm giving it a local variable name which is the app state as you can see here now if we go back to the component for one second so remember this application state that i'm subscribing to it's of type observable of app state so if we go inside of the app state remember we have the data state which is the loading loaded or error so what we need to do is to use a switch statement on the data state so that we can check for when the data is loading or loaded or when we get an error so let me close that and let's go back what i want to do is to create a switch statement so i'm going to add bracket and then here i'm going to do ng switch just like that and then i'm going to set it equal to the data state in the app state so i'm going to say app state dot data state so the data state in the app state remember that's our enum that's going to be like loaded loading or error so we're going to be switching on the different states of the application so all i have to do now i'm just going to switch to see if inside of the app state the data state is loading then i'm gonna show this piece of ui so i'm gonna go here and i'm gonna do ng switch case and then i'm gonna set this equal to the loading state so i'm gonna bring in the data state inside of the class so that i can use it here so that i don't have to type this manually so let's go back in the component and right under here i'm going to put a space so that we can separate the um constructor from everything else and then i'm going to define another variable which is going to be read-only because i don't need to use it in this class at all and that's going to be the data state so we're going to call it data state and we're going to set it equal to the data state so we're going to say data state so that's our enum that we define in that way we can use it in a component and of course we can't change it because we make it read-only so i'm just going to copy this name and then go back to the component so since we're switching on the data state of the app state and remember if we go back again inside of the app state the data state is of type data state so these two types are the same so this variable that we just defined here and the data state on the app state they are the same type which is the same enum so that means we can use this variable that we define which is this data state here and the ui so that we can switch on the different data state that we have in the app state so here i'm going to say data state and we're looking for the loading so let's go back real quick i just need to see what i named these so it's loading state so i'm gonna copy this go back and then paste it here so we're saying hey we're gonna subscribe to this observable and then we're gonna switch on the data state and then we say well whenever we have the case of loading then we're gonna show this piece of ui and of course you already guessed it we're gonna do the data state loaded on the second one so whenever the data state is loaded so on the opening ng container right there i'm gonna add the loaded state so i'm going to change this to loaded so whenever the data is loaded then we're going to show this piece of ui and then i'm going to do it for the last one which is going to be the error state so i'm going to copy this and collapse this so we have this last ng container where we're checking for errors and then we're gonna show this error right there so i'm just gonna go here and then paste it and what did we name the error state we call it error state so i'm gonna copy this and then go back to the ui and then paste it in here so whenever we have an error state it's going to show error and we're going to show the error message here in a second and whenever we have the loaded state we're going to show the table and everything and whenever the data is loading so we have the loading state we're gonna show the spinner so now we can go back to the ui and check it out so let's go back and now you can see we don't have the spinner anymore and we don't have the air anymore and i can show you that real quick since we have a delay in the back ends so if i go ahead and refresh this you're going to see we have the spinner because we're in the loading state and then the data is back then we have the loaded state so now we have the data and you can see now all the other uis are gone so that's what we're going to be using to manage the ui we're going to use the application state itself and then we're checking on the different states and then show different pieces of ui depending on that state what i want to show now is all the servers that we have because we know that the data is loaded so if we right click and inspect this a little bit we should see an object as you can see here and then we have the data inside of it we have all the servers so all of our data is in here as you can see so we can show all this information on the ui so i'm gonna go ahead and maybe minimize this a little bit let's go back to visual studio code and what i need to do is to just loop over all this array and then print all the information as you can see here that we need to show to the user and we're going to do this in the table body so what i'm going to do inside of the body is to just loop over everything so i'm going to do an ng4 so we're going to do ng4 and let's say let server so we're gonna call every item in the array or server because it's a list of servers and then we're gonna say of and then we're gonna call the app state and then we need to go inside of the app data that's supposed to be the app data and then inside of the app data we have the data and then inside of the data which is an object we have all the servers and if we want to get the index we can say let i equal index so i'm not going to use the index in this case but i just want to show you you can get the index as well so this is how we're going to loop inside of the application state to get all of the servers so if this is a little bit confusing i'm going to show you what we're doing so let's go back to the component so we're looping over all the servers inside of the application data which means that this object that we have in the ui is the entire objects that represent the application data so what we need to do is we need to go inside of the app data which is of type t in our case we're passing in this type the custom hp response so our data so our app data in this case is t which is the custom htv response and if we go inside of that we have this data object and inside of this data object is where we have all of our servers so that's why we have to go through the application state go inside of the app data and then go inside of the data and then go inside of the servers so we're looping over all the servers and then at this point we can just show all this information that we have to show here so i'm gonna put double color braces for string interpolation and then we need to say server dot ip address and i'm going to copy this and then highlight this and do double color braces and then just paste this so server.name and then we're going to do it again for the memory we're going to say memory and we're also going to do it for the type so highlight it double curly braces space paste and then space again just to test this out let's go back to the browser and see if we have anything and as you can see we have all the information here already so we have all of our information so let's fill out all the rest of the information so that we can have a working ui so let's go back to visual studio code let's go ahead and add the image so here i'm gonna say this is the server.imageurl so image url and we can use the property here so we can say bracket all right that should work and we can do the same for the alt that we have on the image tag so we're gonna say alt also put this inside bracket and then we're gonna give this the name of the server so we're gonna say server that name so in case that we can't load this image then this is going to be the name of the server that we're going to show if for some reason we can't load that image so now if we go back we should see all the images are there so let's go ahead and work on the status so the status is going to go in here so we can copy this right there and then go in this badge and then paste it and then we're gonna say status so we're gonna say status just like that and if we go back let this load we're gonna see server up server down server up server down so what i want to do is i want to show server up or server down but i don't want to show the underscore so i'm gonna close this and zoom in a little bit so you guys can see clearly so we have this underscore which is the way it is in the backend because we have server underscore up server underscore down but i don't wanna show this i want to show server space up or server space down i don't want this underscore because i want to make this more user-friendly and also we need to add a different css class depending on you know the server is up or if the server is down so let's go ahead and work on that so let's go back to visual studio code and we need to add another class but dynamically so i'm going to put a space and then go down and then i'm going to use ng class so i'm going to say ng class because we need to add a class dynamically and then i'm going to put it in bracket and then i'm going to set it equal to another bracket and then what i want to do is to check the status of the server so i'm going to say server so the server in the loop check the status and then i want to see if the status equal the server up and we can use the same enum that we used for the data state so let's go back here and i'm going to do another read-only so read-only and we're going to say status and set this equal to the status so that's the enum that we created that's coming from our you know and just to remind you if i go inside of this class that's the enum that we're using inside of the interface that we created for the server so if we go back again inside of the server and at the service so in the interface servers remember we're using the status for the status of the server so that can be either server up or server down as you can see here server up or server down or all but we're not using this all we're only using this all in the front end we're only using server up and server down in the back end and since they have the same name you can see that i named them the same the same in the back and the front end so that means i can use this in the front as well when i do a comparison it's not going to break because i give them the same name so i'm going to close all this and we're going to go back to the ui and again i need to bring this in and that's what i just did here so that i can use it in the ui so i'm going to copy this go back here oops and paste it in and we're going to check for server up so i'm going to do that server it's auto completing for me because i'm using a type so i'm checking to see if it's server up so i'm gonna put a question mark and i'm gonna scroll this over a little bit so you can see so i'm gonna say if the server is up then add this class and i'm gonna put a space because i don't want this to be the same because if you don't put the space then this badge is going to be one string so make sure you put a space and then we want batch success so we're going to say badge dash success and those are bootstrap classes and i'm sure you guys are familiar with those and then i'm going to put a column and then do batch danger so that it can be red then i'm gonna copy this paste it here and change this to danger and then again for the status we can do something similar because i don't wanna show this server underscore up i want to show server up without the underscore so let's do something similar we're going to check to see if the status is up so i'm just going to copy all of this and then paste it in here you can do the same in here as well so we're checking to see if the status is up then we're gonna say server up so let's just copy this and here we don't need the space and we're just gonna remove the underscore just like that and if this is not the case then we're gonna say server down so we're gonna do server down so instead of showing the actual status which is gonna be server underscore up or server underscore down we're checking to see if it's server up then we're gonna show this string instead otherwise we're gonna show the string and of course we're doing the same by adding a class dynamically which is gonna be the batch success if the server is up which is gonna be green or batch danger if the server is down so now if we go back everything should work and you can see we have server up without the underscore and then it's green server down without dealing the score and then it's red so our ui is coming together nicely and the next thing i want to work on is this ping right here because we don't want to show the loading and the little ping icon or the little router icon at the same time we only want to show one and then whenever they ping one server we're gonna show the loading only for this specific server so let's go ahead and work on that so let's go back to visual studio code and i want to go to the component so let's go inside of the component and i want to create a filter subject so i'm going to go down and then create a private field and i'm going to call it filter subject and it's going to be a subject so we're going to say filter subject set it equal to a new behavior subject i'm going to do new behavior subject and we have to give it a type and that's going to be a string and we also have to initialize it with an initial value because it's a behavior subject so here i'm going to give it an empty string so this is going to be the filter subject and then i want to create another observable of that filter subject so i'm going to say filter let's just copy this name and i'm just going to put filter and call it status for example filter status and put a data sign because it's going to be an observable and then i'm going to set this to this that filter that is observable not the filter status this is supposed to be the filter subject and we want it as an observable so this is our behavior subject the filter subject and the filter status which is why we're going to be using endo ui is unobservable off of that filter subject and if you guys are not familiar with rxjs and behavior subject and subject you can go ahead and google it i don't want to go into the explanation right now because it can be a little bit confusing so i'm just going to show you how i'm going to use this if you guys want me to you know make a tutorial about behavior subject and rxjs in general then i can do that i have a lot of courses pile up and a lot of tutorials pile up and i have to finish those first and i don't have anything in the near future on my list to do with rxjs but if you guys really want it just let me know i can actually do it but we're going to be using this subject in the ui and then we're going to react to it accordingly so that we can show the loading spinner or the little icon to ping the server so now we can go back into ui and use this observable so that we can determine when we want to show the little spinning icon or the router icon so let's go back to the ui and we want to go into this guy right there so and here what we want to do is to either show this ping server with this material icon or we're going to show the spinner with the font awesome spinner so up here i'm going to do ng if so i'm going to do ng if and set it equal to and then i'm gonna put parenthesis and i'm gonna pass in the observable remember this is an observable so we have to subscribe to it and we can do that by using the async pipe so i'm gonna do a sync and then we need to check to see if it's empty so we're going to put empty string or we want to make sure that this subject doesn't equal the current ip address of the current server and the iteration so i'm going to copy this again one more time and then go over here and then paste it and this time i'm going to use the nat operator so i'm going to put a question mark here and then i want to make sure this doesn't equal the current server and the iteration for that ip address so here i'm going to pass in the server ip address so that's the first condition that we need for the second condition so for us to show the little spinner we just have to check to make sure that the current filter status which is pretty much going to be the ip address actually equals the ip address and the current iteration so we can just copy all this and then go down and paste it here and i'm just going to remove all of this and then just check to see if it equals the current ip address in the current iteration for that server so if this filter status equal the ip address then we're going to show this if it equals empty or it doesn't equal the current ip address and the iteration then we're going to show ping server and that's going to do the trick for us and remember we initialize this with an empty string so currently this condition should be true and we should show ping server so let's go back to the ui and you can see we have this little icon here that says ping server and if we go back to vs code real quick the way that we're going to control this filtered status so this observable that we defined here is whenever we're going to ping the server so whenever we ping a server we're going to call this subject and then we give it the current ip address so whoever is subscribed to this they're going to react to it and the ui and they're going to be like okay this equal the current ip address of the server and the current iteration then it's going to show the spinner and this is going to be no longer true so it's no longer going to show the little icon to ping the server and another thing i want to point out is me using unobservable as you can see here i'm using a subject and then i'm using an observable so why would i do that when i could just use a simple variable like i can just define a variable that's not unobservable and that's what i'm going to tell you at the end of the course i'm going to tell you why we take this approach and some of the benefits that you can get from using this approach one last thing i want to do in the ui before we actually continue adding the other functions that we need so the functions to add a new server filter the servers and delete the server i want to add the error and the ui as well so remember if we go back inside of the application state we know there is a scenario where we can get an error so which is going to be a string so back here when we subscribe to this observable we know that whenever we get an error which is going to go inside of this block then the error message is going to be in here which is going to be a string so off of the application state we'll have an error property as you can see here so this is the interface that we're using so application state it will have an error property which is going to be a string so we can capture this as well and whenever there is an error we can show this string to the user which is being captured as well in our service so if i go inside of the service we're catching it right down there and we're just showing this generic message for whatever error that occurs with the status so i'm gonna go back inside of the ui and scroll down so here we're showing this error which is just hard coded so we can turn this into the actual error that we're getting from the backend or we're just getting in general so i'm going to put double curly braces access the application state so i'm going to have state that error because we know that property is going to exist so if there's an error then this ui or this container is going to show and it's going to have this little message in there as you can see here that's going to be our string error so if we go back to the y we shouldn't see any changes because there's no error but i can simulate an error and then i can show you what that looks like so let's go back to the back end and i'm gonna minimize this a little bit so what i'm gonna do is to just make this throw an exception after three seconds so i'm gonna go down here go down and then i'm gonna say throw and let's make this throw a runtime exception so i'm gonna say runtime exception and then pass in a message here i'm gonna say something went wrong and put a semicolon here and we need to just comment out all this code this is supposed to be new so we're gonna throw a new runtime exception or we can even throw this exception since we already have it here and i don't know if this exception takes a message in the constructor but we'll see all right so we get no errors so this constructor it actually takes a message so we get no errors so we can run the application and then after three seconds it's gonna give us an error which is gonna be the string we're not really capturing this and anything and i can show you how we can capture this so let's go ahead and rerun this and we're going to test this out all right so the application is running as you can see here so let's go back to the ui and refresh and wait you're going to see an error occur and then we get 500 so we get the ui piece where there is an error so if you want to capture the error message so let's see if we can inspect this a little bit so if i go in here right and i go into the console and i have this http error response so that's from angular this is the object that they use to capture http error response and you can extend this and if i go inside of this so if i extend this a little bit you can see that we have this error here and we can capture this information as well we can look at the message if i extend this a little bit more and then we get a 500 okay so that's bad because 500 is an error so you can grab whatever you want from this error message but if you want to capture the error that we set up in the back end like this something went wrong so let's go back to the back end so if you actually want to capture this then you need to do exception handling and this is something that i'm not covering in this course but this is extremely important when you're building an api because you want to be able to capture all of your exception and then return something to the user like something that the user can understand they can see okay this is the air that occurs let me see how i can fix it and this is something that we can do as well and you should do it whenever you're building your api but in this particular case i'm just not doing the exception handling but it's super super important you can see that we have the exception that happens here so interrupted exception and here's the message something went wrong but i just wanted to show you that if we have an error then the error is going to come up here and you will see that we have the ui piece that represents the air so let's go back to the back end and i'm gonna just undo all this because we don't need to send this error and i'm gonna remove this line as well and then i'm gonna go ahead and run the application so run stop and rerun all right so everything looks good if we go back again and refresh we're in loading state and we get our data all right so everything looks good so in the next videos we're going to be working on the other functions that we need to you know filter everything add a new server and then print the report and also to be able to ping a server let's go ahead and work on the ping at this point so let's go back to the application and i'm gonna scroll down and copy this function and i'm gonna paste it down here and i'm gonna change the name to ping server so we're gonna say ping server so ping server and this is gonna take the ip address because we need to know which ip address we're gonna be pinging and we're gonna pass this in as a string and this function is gonna return void so the return type is fine here and we're gonna keep all this code the same and the first thing i wanna do if you guys remember we define this filter subject so that we can you know shoot a little spinner whenever we're pinging a server so the first thing i want to do is to emit something on this subject so that the server's ip address can have the little spinner instead of the router so the first thing we do whenever we call this function to ping a server is to pass the ip address to the filter subject so i'm gonna call next on this and then i'm gonna pass in the ip address so that way the server with that ip address will have the little spinner instead of the little router so we're gonna show the spinner so that way the user knows that we're pinging the server for that specific ip address so that's the first thing and then the second thing is we have to call the ping so i'm going to remove this server and then call the ping and then pass in the ip address again so i'm going to say here's the ip address make the call to the back end ping the server now remember when we ping a server in the back end it returns the server that is ping so if the status was changed then we're going to have the server and the response so what we need to do is we need to wait for the response so we're gonna do exactly what we're doing here and then once we get the response we're gonna set the server that we got from the backend to replace the server that we have in the front end for that specific server that they just ping and as you can see at this point i'm not retaining this data that i get so whenever i get this data i just pass it to this observable so i don't have any way to access it in this specific component so what i want to do is to define a variable and then i'm going to store this response inside of it so that whenever i get this response i can look for that specific server and then replace it and then pass the response again to this observable so i'm going to go ahead and scroll up and i need another behavior subject so i'm going to put my mouse on this line i'm going to press shift alt with the down arrow key so that i can make a copy of this line and i'm going to rename this i'm going to call it data subject and this is going to be of type custom http response because this is the response that we're receiving from the backend oops so i'm going to copy this and then paste it here instead of string and we're going to initialize it with no we can put null or undefined either one so we're going to start with null so i'm going to copy this data subject and in the ng on init whenever we get the data so on this line right here we're gonna see this data subject that next and then we're gonna pass in the response because that's what it's expecting so all we're doing here is after we make the first call to the back end so this engine unit is gonna be call and once we get a response the first thing we're going to do is to save the response inside of this data subject so that we can have a copy of this data in the component because we're going to need it later down here so that's all we're doing so i'm defining this data subject which is a behavior subject of the response or the custom response which is what this is like if i hover over this you can see that it's the custom response which is a response that we get from the backend with all the servers the status code the message everything so we're saving this data inside of this data subject now i'm going to scroll down so here then whenever i make the call to the backend i'm going to show the spinner for that specific ip address because this is what this line is doing line 41 and then i'm going gonna call peng on the surface give it the ip address so that you can make the call of the back end and then try to print the server and all of this is being done in the back end so we're doing the same thing again and we're gonna come back to this in a second but now we're not gonna start with the loading state because the data is already loaded so whenever we initialize this engine in it we got some data at some point right so when we call this bank server we're not going to say the data is loading because the data is already there we already received the data so we have to change the state and then we're going to say loaded state because the data is loaded and then for the data so i'm going to copy this and i'm going to paste it here so for the data we don't have this response right because at this point we're giving the observable something to begin with so that's with the start with so we don't have access to this response which is only going to happen whenever this is resolved this observable that's going to make the call to the back end whenever it's resolved so we don't have access to this response in here so we have to give this the existing data so the existing data which is right here so we can call this so here i'm going to say this that data subject to get whatever you save in this data subject you call the value so this is going to give us all the value or whatever we saved earlier you can see that it subtype custom issue response so we're going to give this to the ui to begin with so when this function is called it's going to say all right i need to make a call to the back end but i'm going to start with this data which is state loaded because we're not fetching the data for the first time we unloaded state and the data is whatever we saved initially after we call ng on init so when we call engine init we save the response in this data subject and then here we're just accessing this response which is going to be pretty much the same response so we're passing it here to start with while this http call is being made so now all we have to do with this response whenever we get it is to loop through all of the servers that we have saved in this data subject and then replace the server that we get back from the backend inside of this array so that we can update any updated information that we might have gotten from the backend which in this case is going to be the status so if the status of that particular server that we're trying to ping if this status was updated then we will have the updated status and then we can show it to the ui so i'm going to come here and i'm going to say this that data subject and then i'm going to access the value again and on that value you can see that we have all the properties that we're supposed to have because we typed this correctly so what i want to do is to access the data so i'm going to access the data and i know the data is an object and i need to access the servers so i'm going to access all the servers so the servers it's an array if you guys remember and i need to find the index so i'm going to put opening and closing bracket so i need to find the index of the server that the user ping and then replace it with the server that we get in this response so that we can get any updated information so what i'm going to do is i'm just going to use the find index that you can call on arrays and then give it a condition i'm going to go ahead and put this on the new line and all i want to do is i want to access all the servers again so i'm going to copy all this because this is the only data that i can work with that's the data that i have saved and then i'm going to say find index because we need to find the index of some server in this list which is the server that the user ping and then i'm gonna say for every server in that list we want to execute some piece of code with the callback function and again i'm gonna put this on a new line and i'm gonna say if the server that id equal the response that data that server because remember when we ping a server in the backend in this case what we get in the data is just one server not the list of all the servers but we get a server and if we go back real quick just to make sure you guys can connect all these dots if we go back in the custom hd response you can see that the data can be sometimes a list of server which is the case when we call this servers we get a list of servers or it can also be just one server and that is the case when we ping a server so whenever we ping a server this response data will contain a server it's not going to contain servers but just one server and what we want to do is to access the id on that server so whatever we get from the backend whatever server we get from the backend we're going to check to see where these ids are the same so we're going to loop through all the servers that we currently have and the front end and we're going to say we need to find the index so this is going to give us the index in this list right here so the position of that server that we're looking for and the condition we're giving the find index is wherever the server id equals the server id we could also do this for the ip address because we know that the ip address is always going to be unique for every single server but id is a little bit more secure here because we know the backend id and the frontend id they're definitely going to be the same so remember we put the bracket here and then we put this code inside of it so all of these two lines so line 46 and 47 is going to return just an index and you can see that we have the opening and closing bracket so we're inside of the servers we're going to have this index for that particular server that the user just ping so in that case then we can say set this server so for whatever index you find for that server set it equal to the response that data that server and that's how we're going to update our data subject because the only thing we have to do is to just replace this server that the user ping with the server that we get in the response just to get any updated information and then at this point then for the data we can also pass the same value because we just updated it and then we're just gonna paste this here and then we have some cleanup to do so i'm gonna copy this line and then paste it down here and set this to an empty string because remember after we process everything we have to set this to an empty string so that we'll stop showing the loading spinner and then show the little router so that the user can ping the server again if they want to and we're gonna do this even when we get a failure so i'm gonna go down here and paste this subject next and then pass an empty string so that we can stop showing the spinner even when we have an error because we don't want to you know show an error say hey something happened we couldn't ping the server and then the spinner is still spinning we have to stop the spinner and that's pretty much everything you have to do for this and another way we can do this just to make sure you guys can see this clearly so i'm going to remove this and i'm going to define another variable up here i'm going to say constant index and then set it equal to this just like that all right so maybe this can make more sense in case you didn't understand clearly so i'm gonna see if i can put this on a new line so you see that i'm defining this index here and we're going to access all the servers and then find the index where the server's ids are the same and you can see that's what i'm doing here and we need to close this all right so we're going to find the index by say for all the servers loop through them wherever the ids are the same then that's the index that you're going to give us for that specific server in the array and then with that index so if i make this a little bit smaller if i put this all in one line we're going to say index all right so remember this is all of our data so this is all the list of the servers so for this particular server at that particular index replace it with this server that we just got from the backend so maybe when i put this on two lines it can be a little bit clearer for you guys but we're defining this index that we're trying to find in the existing data that we already have in the front end we're just looping through them and then we call define index which is going to give us the index and then we set the condition we say wherever these two ids are the same so the id of the server that we're looping through that we already have in the front end whenever these two ids are the same so the id of the server that we got from the backend you can see we're accessing it from the response whenever these two this condition is met then that's the index we need to find so this is going to give us the index of this particular server and the array and then once we have this particular index we're going to say all right so now that we know the position of this server and the list then in that same list at this particular position replace that server with the server that we got from the backend so that we can get any updated information and that's only going to be the server status because that's the only thing that can change whenever we ping the server we're not going to change anything else and then after that then this data subject you can see it right here is updated and we just return it as the data for the front end and then after we do that we stab the spinner so we pass an empty string to the filter subject and then we do the same if we get an error and that's all we have to do for the pink server so now what we need to do is to hook this up in the ui and just see it in action so i'm going to scroll over a little bit and just copy this pink server function name and go back to the ui and we need to go right here so wherever we have this anchor tag i'm gonna put a click event here so i'm gonna say open and close parentheses and then click so we're registering a click event and whenever this occurs we want to call our function remember we're still in the loop in the table so let me scroll to the right a little remember we're still inside of this table so we're looping through all of the servers you can see here so we have access to each server in their ip address so here we can say server that ip address so we're passing the ip address to ping server which is what it's expecting and that's pretty much everything we have to do in terms of the ui so whenever the user clicks on this button we're gonna call ping server passing the ip address and then we're gonna do all of this processing so let's see if it works let's go back to the ui all right everything looks good so i don't have any issues so now let's go ahead and try to ping let's say the first server and ping okay so it looks like it was successful let's open the developer tool just so we can take a look so if i clear this and refresh so that we can get a new set of response so here's the response and you can see inside of the data i have four servers all right so the first one is 160 as you can see here so let's see if we can ping it so ping all right so let's go back you can see that the call was successful so we got the 200 from the backend and the message was ping success inside of the data we have the server which is the same server with id1 so everything seems to be working so let's do another one gonna collapse some of these let's do this one let's do the 58 because i don't think i have this 58 connected so it should take some time we should see the loading spinner and then it should give us you know server upping field so let's do this you can see it's spinning now but only the server and then you can see bank fail and inside we're gonna have that particular server with any updated information in that case this was already down so the server down is still the same so the ping seems to be working and you can try it for all of them it should work just fine and okay so that didn't work so i don't think i have this 21 either in my network so if we ping that one it should take some time and then the server up should turn to server down so let's try that one okay let's let it go you can see server down because we updated the server in the list so everything is working as expected so i'm gonna scroll over a little bit and just copy this pink server function name and go back to the ui and we need to go right here so wherever we have this anchor tag i'm gonna put a click event here so i'm gonna say open and close parenthesis and then click so we're registering a click event and whenever this occurs we want to call our function remember we're still in the loop in the table so let me scroll to the right a little remember we're still inside of this table so we're looping through all of the servers you can see here so we have access to each server in their ip address so here we can say server that ip address so we're passing the ip address to ping server which is what it's expecting and that's pretty much everything we have to do in terms of the ui so whenever the user clicks on this button we're gonna call ping server passing the ip address and then we're gonna do all of this processing so let's see if it works let's go back to the ui all right everything looks good so i don't have any issues so now let's go ahead and try to ping let's say the first server and ping okay so it looks like it was successful let's open the developer tool just so we can take a look so if i clear this and refresh so that we can get a new set of response so here's the response and you can see inside of the data i have four servers all right so the first one is 160 as you can see here so let's see if we can ping it so ping all right so let's go back you can see that the call was successful so we got the 200 from the back end and the message was ping success inside of the data we have the server which is the same server with id1 so everything seems to be working so let's do another one gonna collapse some of these so let's do this one let's do the 58 because i don't think i have this 58 connected so it should take some time we should see the loading spinner and then it should give us you know server upping field so let's do this you can see it's spinning now but only the server and then you can see bank fail and inside we're gonna have that particular server with any updated information in that case this was already down so the server down is still the same so the ping seems to be working and you can try it for all of them it should work just fine uh okay so that didn't work so i don't think i have this 21 either in my network so if we ping that one it should take some time and then the server up should turn to server down so let's try that one okay let's let it go you can see server down because we updated the server in the list so everything is working as expected now let's go ahead and work on the filter so whenever we select one of these filters we want to see the list filtered let's go back to the code again and i'm going to copy this function again so copy all this scroll down and paste it down and this is going to be the filter server so i'm going to rename this to filter servers all right so whenever we're filtering our server the only thing we need is the status so i'm going to change this to the status and this is going to be of type status and this is supposed to come from our enum i don't need to do this so i'm going to go ahead and remove this line remove it down there as well so that i don't forget and i'm going to remove everything inside here because i'm not going to be doing this processing and this time we're not going to call the ping we're going to go ahead and call the filter so filter and we need to pass in the status status that we got from the function up here so this status and then we need to give you the data so the current data you already guessed it it's inside of this guy right here so you can see how important it was for us to keep a copy of this data because we're gonna need to pass it around so oops i'm gonna pass it here so we're passing in the data so the current http response that we have and we give it the status and again the data is loaded so we're still in loaded state and we're keeping the current ui the way it is so we're not changing this data at all so we're giving it the same data so this is going to stay the error of course this is going to be the same and we can put a semicolon here just to end this line this is not required but i'm a java developer so i like my semicolons and what we're going to do is wait for this response so we're going to do exactly the same thing so everything is the same but this time we need to use this response so we're not going to use this data we're going to pass the response so remember this is our data because we're not making another call to the backend when we call this filter we're not getting any new data we're not calling the list so we have to preserve this data whenever the user filter back to all so if the user filter to server up then we're gonna have all the server up in here so that's the response we're giving back to this observable in this component we still keep a copy of the original data inside of this data subject so you have to be very careful we don't want to return this data subject we want to return whatever filtered response that we get from calling the filter observable and then we pass it here so that this data will be intact so if the user filter back to all again we say okay we get the status this function is called we give him all the data so all the data with all the server that we got whenever we uh initialize here and then we got all this data from the back so you have to be careful with that because data integrity in this case is very important we don't want to override this data and it will be stuck in the ui because we'll get rid of the existing data that we get so you don't want this user experience and just to recap one more time when we call this function and the ui the only thing we're gonna need from the user is the status so we're gonna say okay what status do you want which they're gonna pick by just selecting one of them in the drop down and then we're gonna give this filter all the data that we already have in this component so all the data that we got from whenever this component was loaded or whenever like if the user ping the server like the latest data that we got is gonna be inside of this data subject so all the data all of it and then when we call the filter we give it this fresh data and then it's going to give us a response and then that's the response we're going to give to the front end or we're going to give to this observable because if this is filtered server then we don't want to filter this data subject because then we will lose all the data that we had and then if the user select all then we have to give the user all the data or all the servers then we won't have them because we filter that list so we want to make sure that we keep this intact like we don't touch this and we return this response that we got from calling the filter on the service and everything else is the same we're going to start with the loaded state because the data is loaded and then give the existing data to the ui and now we just have to hook up this function in the ui so i'm going to copy it again and then go back to the ui and let's make our way to this drop down list it's right here so this is the drop down list you can see the select so that's our drop down list and you can see everything is already set because i already did this for us so server down server up and then all and these are the text that we're showing to the ui so now we just have to hook this up in the select so here we're gonna use the ng model change because we need to watch for a change in the select so we're going to say ng model and then change and then set this equal to our function so equal quotations and then pass the function and here we're just going to pass in the event so whatever the event is it's going to be whatever the value is inside of the option so whenever this energy matter change occur which means whenever this select one of these options is changed then the event is actually going to be this value right here so we're passing this event which is pretty much this value that we're passing into this filter server and then by default we need to give it a value so we're going to say ngmodel let's set this equal to all so we're going to say all so because we add this on this select then it's not going to know what the default is so the default is going to be with this ng model and we're going to set it to all and this is really not going to take effect like this is not going to be called because when we get the data it's this ng on init that's going to set the data for us so it's going to be the default but it's not going to be called on initialization it's just going to be here to show the user at this current moment you're looking at all the servers nothing has been filtered so now let's go back to the ui and i'm going to open the developer tool again i think we're logging some of this stuff and let's see if we can filter so server up you can see that it's filtered and we get our log and i can do server down you can see that the list filtered now if i go back to all servers then we get all the servers so this functionality is working as expected and you can go ahead and play more with it i already know that it's working but go ahead and you know play around with it it should be working as expected as you can see here so now let's go ahead and work on the search server so we're gonna make sure we can capture a new server when the user fills out this form and then whenever they click save we're gonna send that to the backend and we're gonna show that new server in this list right here so let's go ahead and work on that so i'm gonna go back to the code and i'm just gonna copy this ping and i'm going to scroll down and then paste it i'm going to call it save server so we're going to say save server and this is going to take the ng form so let's call this server form and it's gonna be of type ng form so this is ng form coming from angular as you can see it's coming from angular forms and that's what we're gonna take in here we don't need to do anything with this filter so i'm gonna go ahead and delete this line and we're going to call this surface this time we're not going to call the ping we're going to call the save so we call the save and then we're going to give it the form value so the form value it's going to represent a json object of the data that we pass into the form so we're gonna say server form that value and that's how we're gonna pass here if i hover over this you're gonna see that it's gonna give me the type any but that's not a problem because it's gonna be converted into an object with the keys and values that we need for the back end so the back end will be able to interpret it but if you want you can cast this here for example you can put the diamond again and then you can say this is going to be a server you can do it that way so that should work as well or another thing you can do you can pass it in as a server so you can put it like this and then you say as server so either way it will work it's not going to be a problem and we're getting this error because it looks like it's important server from the wrong place so let's look at our import this is not where we want to import that i'm going to delete it and see if i can re-import it quick fix and it's supposed to come from our interface just like that so you can do it that way or you can do it in front with the diamond but it doesn't really matter because this is not going to cause a problem even if we didn't cast it i just wanted to show you that you can actually cast it if you want to so when we call the save what the save is going to return us from the back end it's going to return us the object or the server that we just saved right so we're gonna do the same thing again meaning when we start we're gonna start with data loaded and then we're gonna keep the existing data on the ui so that we don't have any glitch in the ui like you're gonna see the ui disappear and it reappears again when the call comes back or if the call takes a long time then it's just going to disappear and then come back we don't want that to happen so we always want to have our data to be shown to the user because the data already loaded initially when we uh call ngon in it like i already explained now the next thing we want to do is we're not going to do all this so i'm going to just delete some of this stuff what we want to do when we get the data so let's just delete all these lines just so you guys can see this clearly so when we get the data back right we're going to still return this data but we're going to modify it and what we're going to do is the new server that we're going to get back we're going to edit to the list of servers inside of this object which is uh containing all of our information or all of our data and we can do this pretty simply so we can go down here and we can call this data and i call the data subject so this is all the data that we have in the application and what i want to do is to just push on a new object on it or i'm just going to change the information inside of this data object and then what i'm going to do is to just pass in everything that i already have so let's go in a new line and i'm going to pass an object and i'm going to copy everything that i have in the response so i'm going to do the spread operator again copy the response and the only thing that i want to change is the data and remember the data is an object so open and close curly braces you can see that the error is gone because we can actually pass in an empty object and what we need to do here is to just put the new server on top of the list or on top of the array and then at the existing ones after the first one so we can do that pretty easily we can just say we're going to override the servers remember this amp check has a property called servers so we're going to say for the servers which is an array we're going to define the bracket so that we can see this is gonna be an array what we're gonna do is to pass in the server that we got back so the server that just got saved in the backend which gets returned to us from the api we're gonna put that server at the beginning of our array so we're going to say response that data and we need to access the server so that's going to override the data particularly the server's property inside of that object and then replace it and then we need to pass in the existing servers so for that we know where to go get it so we're gonna say this that data subject that data that's oops we have to do that data uh we have to access the value first and then data and then we need the servers so we're gonna say servers and of course we're spreading this so we need to pass in the spread operator here as well and we don't need to do this response again just to reiterate we're gonna change this data we're gonna push next onto it so we're gonna push a new object onto it and the object we're going to push is everything that we got from the response so that we can capture all the metadata in the response and the only thing we're overriding is this data so while we're overriding is the servers because that's what we're displaying on the ui we're going to say for the servers take the first server that we got back from the response put it at index 0 in the array and then give us all the other ones that we already have in the existing data so from the data subject and then we're going to put them after the first one or after the one that just got saved so that it can be on top of the list and after we do this uh there's some cleanup things we have to do so now we have our data it's updated and that's the data that we're passing it here so we don't have to make any changes in the return but we do have to close the model and we're just going to do that the typical javascript way so i'm going to say document.getelementbyid and then pass in the button id so here i think i named it close modal so that's the idea of the button and once we get that button we can just call the click function on it because we know it's gonna exist because we're accessing a button so this is gonna close the modal and then the data is gonna be updated after we return this and the user will see the new server that they just added it's going to be on top of the list and then after we do all this another thing we have to do is to reset the form so i'm going to call the server form and let's call reset form and then here what i want to do is to pass a new object because i want to insert the form but i want to set the status to be a default and that's going to be the server down i don't think i need to put space here but i'll put space here so i'm going to update the status so you can see it's coming up here for the status i'm going to say this is going to be this that status so the status that we have in this class and then call server down so we're going to put a default in the form which is going to be server down and that's the only field that we're updating in the form all the other fields are going to be empty because we're not setting anything for them but for the status we're going to say okay the status by default whenever you open the form again after we reset the form we're only going to set the status to server down and you can change this if you want you can put anything you want or you can just reset the form or just call the reset it's gonna empty everything another feature i need to handle is the loading so you remember in the demo when we click the save you can see that the text on the button is changed we give the user an indication that something is happening in the back and so we show them the loading and the button itself we show the little spinner going on so we need to have a way or we need to have a variable defined in here so that we can manage this uh little spinner that we show in the button and this really improves the user experience so for this we're going to define another observable so i'm just going to copy these two lines or i'm just going to highlight them and then i think i have to press shift alt and then down arrow key and i'm gonna rename this to is loading so we're gonna say is loading so that's gonna be the name that i'm gonna give this and it's gonna be of type boolean so i'm gonna remove this custom response and then pass in boolean so by default we're going to start with false of course because we don't want it to be spinning so this is the subject and then we're going to create an observable out of the subject so i'm going to give it the same name just call it is loading and then point it to this is loading right there change this to his loading and then we're looking at it as an observable so now we have this variable that we can use in the ui so the one with the dollar sign we can use it in the ui and then the one which is the subject we can use it to set the value on this is loading observable so now let's go back i'm going to slow down and when we save the server or when we call this function in the ui right well first thing we're going to do is to just set this loading to true so i'm going to say this loading dot next and then post true on it because it's accepting a boolean value as you can see here so i'm going to say it's true now so whoever and the ui is subscribed to this observable then they're going to get this true value and then because we're going to have like an if condition in front of it then it's going to show a little spinner you already see how this is going to go i'm going to copy this again and i'm going to paste it down here so before we reset the form and then i'm going to change this to false because we want to stop the spinner and then i'm going to do the same thing again and i'm gonna duplicate this and see if i can bring this down and i'm also gonna delete this line all right so we're gonna set it to false even when we get an error because we don't want it to keep spinning we want to stop all spinning indicating to the user that all processes on the back end have ended so we're gonna be using this is loading uh observable so the is loading with the dollar sign so that one we're gonna use it in the ui and you're gonna see again why i'm doing it that way you're gonna see that in the end why i'm using observable instead of using just regular uh variable name here now remember we're using ng form so um you can see that we're using it here and we're also going to be using it in the template so we have to add this in our module so let's go back to the main module so the app module and then we're just going to up i think it's already here so the forms module you have to make sure that this is imported so maybe i put it in i didn't realize but you have to make sure that you have the forms module and supposed to come from angular forms so i'm going to close out of this and collapse this now let's go to the ui and then we're going to hook up our form and then hook the form to this function so that we can call this function and pass the form to this function and then execute this logic so now we can see what happens in the ui so let's go back to the ui and we need to scroll down to the modal because that's where the form is so i'm going to scroll to the right so you can see at server model which is just a typical bootstrap model and the first thing we want to do is to go into this form tag so here we have to call our function so first we need to give angular access to this form in an angular way if that makes sense and to do this we're going to set a variable for this form so i'm going to say server form and set it equal to ng form so this is how you make a form an angular form so ng form and then we're going to say ng submit so we're going to listen to the unsubmit so ng submit and then we're going to set this equal to our function so we're going to say save server and then we're going to pass it the form remember it's expecting the form and the form is server form so whenever there is a submit event that occurs on this form then it's going to pass this ng form that we're calling server form pass it to the safe server function and this function is going to execute all this logic so now what we have to do is to get this information so the information from the input and to do this we just need to add ng model on these inputs so i'm gonna say ng model and then copy this and then do it down there for the name and i'm gonna do it again for the memory and do it for the type and then we're gonna do it again for the status so i'm gonna say ng model and we can set the default here as well for the ui so we're gonna say let's say server let's say server down okay so that's what we're going with and then we already have all of our button here so i have this button and i have the icon as well so we only have to show this whenever the is loading is true and also just while i'm here this is the id of the button that we're going to click so that's the cancel button so it's just the typical cancel button on the bootstrap model so we're just going to click this button and it's going to make the model go away so on the submit button so this button by the way you really have to have the type submit here that's how it's going to fire this on submit because it's listening to this submit type down there so make sure your submit button he has the type of submit so now the first thing i want to do is to disable this button unless the form is valid and for the form to be valid you need to have the required annotation so you can see that i have it required on all of the input here so make sure you have that and here i'm going to access the disable so i'm going to say disabled and then set it equal to if the server form is invalid so i'm going to say server form and valid or if it's loading so if we have something loading we also want this to be disabled so what i'm going to do is to subscribe to that observable so i'm going to say ease loading with the dollar sign remember we have to access the observable and then the way we're going to subscribe to it is by using the async pipe so here we're going to say a sync okay so remember to do that and that's why i put the parenthesis because this is now some kind of a statement so i want to separate this into one statement and then for the savings so again we're only going to show this on a specific condition which is this condition whenever this is true so we can just come in here and we're going to just put an ng if so i'm going to put star and then ng if and then set it equal to the condition which is is loading with the dollar sign well actually i can just copy it from here and then paste it here so if it's loading is true and we're subscribing to this observable then it's going to show this spinner and we have to do the same for the saving so i'm going to copy the same statement go into the saving and paste it so if this is true it's going to show the saving and it's also going to show the little spinner next to the button text and then we just have to do the opposite and the add because we want to show it when this is not true so we're gonna go here and i'm gonna enclose this in parenthesis and then just put the nut operator and that's all we have to do here to manage uh while we're showing to the ui so we can also the saving text on the button and the little spinner when is loading is true and when this is true as well we're going to disable the button because we don't want them to click the button when something is happening in the back end we don't want them to send multiple different requests for the same information and when the opposite is true so we negate this statement we're just going to show the add and remember by default we set this to be false so if we go back here you can see that when we create the behavior subject we set this to be false by default so when the ui loads it's going to read this observable subscribe to it it's going to say oh this is false and this is going to turn into true so this is going to show and when the opposite happened then these two are going to be true and then the last one is going to be false and that's pretty much everything we have to do for this form and now we can go ahead and test it out so what i'm gonna do first is to check to see if i didn't get any errors in the console so i'm gonna open my terminal okay so everything is working fine so you see that everything rebuilt and we didn't get any air so that looks good so now let's go back to the ui ui looks good as well so we only have to go ahead and test this out so let's put some random number here so i'm gonna do a new pc uh 16 gig and let's say this is a mail server or something and you can already see that we don't see the little spinner now we see the add text on the button so i can click on add and you can see now we have the saving and it's spinning so you can see that the new one is added right here and we get our response so you can see the created status code tool one and the timestamp and everything and now if we want we can try to ping the server and of course this is probably going to give us an error and you can see that we got the area on our occurred and then we got 500 and you can see the error as well in the console so we're able to uh save a new server and i refresh the page and you see that the server is not at the bottom and we really don't want that the last one to be added we want it to be on top and we can fix this real quick we can either fix it in the back end we can either write a query in jpe in the backend to do that we can use java to do that in the back or we can just do it in the front end and i'm going to show you how we can do it in the front end really easily so let's go back to the code and let's go back here and what i want to do is to scroll down so when we get this information right so when we have ng on in it and we're passing in this app data here so we can just access all of the servers and then reverse the list of all the servers so for the app data right which is an object so of course some hd response we can just do the same thing again so i'm gonna put open and close curly braces and i'm gonna say give me everything from the response so that dot dot i can spread everything from the response and then i can just override the data so here i'm gonna say for the data property so i'm gonna say data and remember the data is an object so open and close curly braces again and then here i'm gonna save for the servers property so servers and i'm gonna scroll to the right so you guys can see what i'm doing here i'm going to say get the response get the data access the servers and then just call the reverse so i can call the reverse and it's a function so we're going to close parenthesis so i want to keep this on one line so i want to make sure you guys can see that so all i'm doing here is just return the state of loaded and then for the app data earlier we were passing in just a response so i'm gonna say okay so now pass me this object which is also gonna be of type custom ac response because it has the same property we're going to say give me everything in the response so everything that we're not overriding we're going to keep it so that's what this is doing and then we say we're going to override the data and specifically the servers property on the data and then this is going to be all the servers just reverse them so now if we go back you can see that the last one is on tap so that was pretty cool i just wanted to show you that you can actually fix that because you don't want the newest one to be at the bottom and again you can keep testing this like if i put some dummy data in there blah blah blah and then hit save and wait for a few seconds and you can see that it's edited at the top and if i refresh it again and let it come back you can see that it's still at the top the reason this is taking a little time even though it's on my local it's because we have this delay in the back end so it's not really supposed to be that slow but just so you guys can see the different states of the application so feel free to remove this delay if you don't like it but i just wanted to point that out so the edit is working now we're gonna go ahead and work on the delete and then on the print report all right so let's go back to the application and i'm gonna scroll to the left so if you don't want this on one line feel free to put it on the no line but i'm just going to keep it like this because i don't want to have it on the i don't know line um let's go ahead and copy the ping again and i'm going to scroll all the way to the bottom and put the delete there paste we're going to call this delayed server so delayed server and we already know we only need the server id but you can put in the whole server here as well so i'm going to pass in the whole server because we're going to need to use some other information on that server as well but all we need to delete a server at least from a backend perspective is the server id and we're going to call the service again this time we're going to call the delete so delayed and we're going to pass it the server id you can see it's expecting the server id so we're going to say server.id and i'm going to delete this line because we don't need this we're not doing this delay down there as well so we're going to return this line with the existing data while we make the http call all the errors all this stuff is going to be the same but when we get the response we're going to do something else so i'm going to delete all these lines again and we're going to start a new so what we want to do when we get the response is to just remove that server from our list and then we turn the new list which is going to be pretty easy so i'm gonna copy this line of code um actually let me type it out so you guys can understand what i'm doing here because at this point i'm assuming you're familiar with most of the javascript array functions or methods so that should be pretty easy for you so we're gonna say hey give me all the data so we're going to say the data subject again and then we're going to push a new object onto this data so what we're going to do this time is we're going to do something similar so we're going to say all right first of all give me everything that you got from the response so we're gonna spread all the response data now we have all the metadata all the time stamp all the new message everything in the response we're returning it now we need to update the servers again so to do this we're gonna access the data property because that's where the servers are so we're gonna say okay for my data all right which is where all the servers are which is on object so open and close curly braces what we want to do is to override the servers so servers is what we're overriding so the list that we're showing so we're going to do is to just say give me this that data subject that value and the data and access all the servers because it's an array and we're just going to filter them so we're going to call the filter method all right and i can actually put this on a new line so i'm going to put this whole thing on no line so remember this is all for the data and for the filter we're gonna have to call a callback function so open and close parenthesis and we're gonna say for every server that we're gonna loop through because when you call the filter it's gonna loop over every element in the array and let's call the server uh let's uh we already have a server defined so that's gonna give us an error because we have server defined here so that's gonna be a name collision so let's say for every server s right we're gonna execute some piece of code so error function we're going to say filter this if the server.id is different from the server that the user is trying to delete so we're going to say server so the server and the method that id and when we filter this it's going to look at this condition it's going to loop through every single server so remember this is an array like a javascript array it's gonna loop through every element in that array it's gonna remove the element from the array if this condition is met otherwise it's gonna keep it so we're gonna say okay look through the first one that's emit this condition no keep it in the in the array second one doesn't meet this condition no keep it in the array and then once it finds the one that meets this condition then it's gonna remove it and then our server list will be filtered and it's not gonna have this server that we just removed from the list or from the array and that's pretty much all we have to do we just filter the array remove this one that we just deleted and then we turn it again to the front end and that's what we're doing here because we're calling next so we're passing in a new piece of data and then to access this data we call the value so now we just have to call this delete on the ui so i'm going to copy this go back to the ui again and this time we need to go to our table so scroll to the left scroll up and this is our table as you can see we have our table here and we need this uh right there so we have to listen on the click event so we're gonna say listen for a click event on this anchor tag and what we want to execute is our function so we're gonna say call this function and pass the server remember we're still iterating so if i scroll up a little bit you can see that this ng4 in the table body right there so we're looping over all the servers so you can see the stable body it encapsulate this anchor tag which means for every iteration we're going to have this same code for every single server that we have so this server is the local variable name that would define up here so it's going to be the server in the current iteration so we're going to pass it here so now we can go ahead and test it in the ui so let's go back and let's delete this dummy data that we put in here so delete that one it's deleted and we get the response back server deleted and remember when we delete the server we get this deleted true which we can use in the front end uh i mean this is really up to you like you can return whatever you want on the successful response as you can see this is going smoothly and that's because i set my back in the way that i want to work with it and the front end and that's why it's so smooth because i know what i wanted to do which means that at some point even before i started doing any of the coding or anything i thought about my design so i might have a course later on design or a tutorial on design like how to think about designing things and bring applications to life but that's something you can be on the lookout for but you have to understand that the backend needs to talk to the front end and you have to make sure that you can do this in the easiest and the most efficient way possible and i'm also going to remove that first one as well so click on delete and you can see that it's deleted so server deleted now we have to go ahead and work on this report so whenever we click print report we want to print this table that we have here with all this information and this is going to be pretty easy this is really going to be just javascript and html and accessing element and then make this work so if you know how to do this in javascript it's pretty much going to be the same thing even though we're in angular because it's just still a javascript that we're using so let's go ahead and work on that so let's go back to the code and we need to go to the ts file i'm not going to copy this because this function is going to be pretty different from all these functions that we have here because we're not going to be making any calls to the backend or dealing with observables or anything like that so i'm going to go to the bottom and see if i can scroll up a little bit so you guys can see and then i'm gonna call this uh print uh report or something you can name this whatever you want and it's not gonna take any parameters and we're just gonna access the html element for the table and then work with that so that's going to return void and then here what we want to do is to just define some variables so let the data type we need to define that and we're going to set this equal to application uh so that's like application slash json like the mime type of a spreadsheet and i think what i chose i looked this up and i chose a vnd that mess dash excel that sheet that mark macro enable that 12. and if this is incorrect like if i have a spelling mistake in this it's just not gonna work and we can deal with this later and then we need to define the table so let's say let table let's say table select and i'm coming up with these variable names as i go so feel free to change them if they don't make sense to you and let's get the tables of document.getelementbyid again and i think i have an id on that table but i don't remember what it is so we're gonna have to go and look up that id so let's go back and uh okay so you can see at the table so this is what we're looking for the table tag right there so we need to copy this id and put it in here just like that okay so we're going to grab the table as an element like an html element and we want this an encoded url so i'm going to define a table html so that's like the html representation anymore html or url encoded a format and i'm going to call the table select that outer html and call the replace because we need to replace the space with the encoded url value for space because if you don't do that then it's not going to work and i'm going to put forward slash space for slash and then og and then i'm gonna say replace this with the url encoded for space which is percent 20 so percent 20 and that's going to replace all the space with this url and coded value for space and this is important because otherwise it's not going to work and then i need to create a link so i'm going to say let down load link so this is going to be like the link to download but we're not going to show it to the ui we're going to click it programmatically and i'm going to say document.createelement because i'm trying to create an element so we're going to say create element we need to create an enter tag so we're going to say a so we can put uppercase a lowercase a but i would go with lowercase and then we need to add this link to the html so we're going to say document that body so we're going to edit to the body and then append child and then we're going to pass in the link so now this link is in the html as a tag okay so that means that at some point we have to remove it because if the user keeps pressing this unless they refresh the page then we're gonna keep adding this element into the html and we don't want to do that because that's just a bad design and then we need to set the href so downloadable link href which is a property on this we're going to set it equal to data and we want the data type so we're going to say data type so data type and then we need a comma so i'm going to put quotes and then command space and then i need to pass in my table so here that's going to be the table html so that's the href on the link so it's data dash this data type we could have all of this in one line by the way and then we pass in the table now we need to give a name to the file so i'm going to say download the link that you do that by calling the download and then you set whatever name that you want in this case i'm gonna say server dash report that xls so that's extension and we just need to click it so let's do downloadable link or that i keep saying downloadable link download link and just click it so after we click it we also need to remove it from the document or from the body so i'm gonna see if i can duplicate this line and then bring this down up i'm gonna do control z because i copy the wrong one so that's the one and then alt down arrow key and i need to do remove so we're gonna say remove child and then we pass in the same downloadable link so every time we click it it's gonna do all this create the link and everything process the table uh give the user the option to download this by just calling the click and then remove it from the from the ui or from the html markup and feel free to simplify this if you if you want obviously some of these variables i didn't really have to define them but feel free to modify this in however you want so now all we have to do is to just call this function on that button so let's just copy this and we're going to go back to the ui scroll up and we're going to look for this button which is right here you can see print report just a regular button and we can just add in a click listener so we're gonna say whenever you hear a click event occur then call our function and of course this function doesn't take anything we're just gonna call it and it's just gonna do everything so now if we go back there's no error everything refreshed properly and i'm gonna go ahead and print and you can see it at the bottom here okay so the reason didn't prompt me is because i'm not logged in so you have to be logged in as a as a user for the browser to prompt you at least that's what i've seen but you can see that it's downloaded here at the bottom and i can click it to open it gonna say yes and there you go so i can enable editing what i usually do well if you've done anything with data you know that a data needs to be cleaned and i can just select all these images delete them and select these two and then delete them probably have all of the borders and bring this in the middle zoom in and there's your data another thing you can do is instead of having this in excel like a spreadsheet like this you can have it as a pdf so to do this which is also pretty easy let's go back to the code and what you can do is to just call the window.print so we're going to say window dot print you can see it's coming up here of course it's a functions we need to add open and close parenthesis and semicolon and we don't want to do all this so i'm going to put all this and comment when we call windowprint it's going to give the default option from the browser to uh save the information and then we can choose to save it as a pdf so now if you go back and click on print again you can see now we have this option and we can just save it as a pdf you can see here we can print it or we can save it as the pdf and you can see it's really really nice it looks really nice so i'm not going to do this i just wanted to show you this let's go back to the code if you want to do this you can but in my case i'm not going to do it so i'm going to uncomment this and then commit the first one out and you can make this function take a value you probably will need to make this like a drop down or something so the user can select or you can add another button i wouldn't add another button because it would be like redundant but this button could be like print report or something and then when they click it they have a drop down like this and they can select either to have it printed in a pdf format or as an excel file so it's up to you i just thought that i would show you this but i'm not going to do this implementation but feel free to do that to enhance your user experience or make it a lot better so at this point we have all of our features working so you can go ahead and test this more of course but everything should be working you know pinging a server uh the latest server editing a server and all that so all this stuff should be working filter all the servers all of this should be working so now what we have to do is to show the little notification so whenever you know we take an action here or we get some response from the back end we want to show a little notification the same one that you see when you're using gmail we have this little black message like a little pop-up window that's very small it's like a little notification and then it tells you you know it gives you some information like hey this was successful or you can't delete this because of whatever reason so i want to implement something similar and it's really overkill for this application but i'm just giving you ideas i'm just showing you how things can be done and then you can take this information and then apply to a much bigger application a much more complicated application so let's go ahead and work on that so the package that i'm gonna use to show the little notification is this package that you're looking at here it's called angular notifier and you can search it on npm you should be able to find it you can see that it has different notification with different colors indicate different type of information to the user and i've implemented this before in some of my other courses or tutorial and like i said it's really overkill for this application but it's a nice feature to have and then i just see it in action and i'm not gonna use all these colorful ones i'm pretty much gonna use just this this one like the black one the default and we're gonna keep the messages very short so that they don't get too long into the screen because i don't want them to be long i want them to be like very small so you can go to this documentation you can see how to use it if i scroll down you can see that you put it in your ng module as uh you know the notifier module you import that inside of your ng module the module you want to use it in and then you pass in some configuration you can see that you call with config you pass in an object which is going to be some configuration and you need to put this notifier container inside of your main container and what else i think we have to import some style as well so we're gonna do this in your main style file to import some of the style that this needs to to work and then you can inject it in your component like my awesome component this example they're showing you and then you you can call it like this and when you need to call the actual function that's going to actually show the notification you call the notifier and then you call notify you give it a type of success that's going to determine the colors and everything and then you pass in the message that you want to pass so it's very very simple to use and that's what we're going to be using and of course you can scroll down you can see a simple configuration so that's the configuration for position distance gap all this stuff so i have a configuration that's pretty fine that i'm going to be using and i'm going to show you that in a minute and what we're going to do is instead of using this the way that you see that they're showing us here we're going to do something else that is a little bit more efficient so instead of injecting it like this in our component and then having to um you know pass it in our module like this which is going to be quite some lines of code we're going to actually create a module so the same way that we see that we have this notifier module right we can create our custom module and then just put it in every module that we need to use and i'm going to show you how this is going to happen so let's go back to the code right so um just to illustrate this a little bit more i'm going to close all this for now and let's go to the app module so the app module is the only module that we have in the application and you can think of the module as a like a space for the app right so this module we're gonna have multiple different modules by the way so this module it has all of this information that it has access to or they they are aware of each other so whenever you want to use let's say a form in any of these files or whatever then you bring in the forms module like you let the context of the application know that you need this module or you need this code or you need whatever angular is doing it back in for forms to be able to use the form the same goes for http client module browser animation module and browser module all this you need to bring in so that your application can work on the ui can like the ui needs this browser module so the same way we have these browser modules and http client modules and forms module you can actually create your own module so i'm gonna take this um this um you know this library and then i'm gonna turn it into a module and then all we have to do is to just bring it in here just like we do like this so what i'm gonna do is i'm gonna take this file right copy it and i'm gonna paste it in so we're gonna go inside the main app paste it in and i'm gonna rename it and i'm gonna call it the notification notification uh remove the copy dot yes right so this is going to be the module that we're going to be using so i'm going to delete all of these because i'm not going to use them we're going to use the ng module from angular and we don't need the declaration so you can see this declaration right here which is an array we can get rid of that and we need the import we don't need the providers so i'm gonna remove that and we need the export so i'm gonna say export and this is also an array okay so now we're getting a bunch of errors because uh we're not really doing anything yet so i'm gonna put this on the new line and remove this for now and we also have to rename this so we're gonna say notification module okay so that's gonna be our module we have to uh stick with the naming convention so that's whatever the name is and then module at the end so this is the notification module and i'm going to go on top of the class and i'm going to define my configuration i'm just going to go ahead and paste it and then we're gonna talk about it a little bit so this is really uh let's go ahead and import this well we're not gonna be able to import this because we didn't install the dip in the library so let's go in and we didn't even do the most important thing so let's copy this and let's go back to my terminal gonna stop this yes paste this and then after that we wanna say ng serve so after we install this we're just gonna run the app so i'm going to minimize this or just bring the code back up so i'm going to give this a few seconds and see if i can up there we go so i can import this now so make sure it comes from the angular notifier right so this is the options or the custom notification options or the configuration right so we're gonna need this configuration so that we can define how we want the notifications in the in the ui so i want mine to be uh horizontally they're gonna be on the left and then i want them to be at the bottom 12 i don't know what this unit is in but that's a distance from the from the screen on the left that's this distance from the top i believe and we're going to use the material theme and hold a wide five millisecond and you can see all this thing that i'm um you know putting in here this animation again you need to have this browser animation module for this thing to work because it's using this browser animation module and i'm just passing in some values here just to make it a little smooth but the most important ones are this behavior and the position so the position is pretty important you have to set where you want this thing to be and then all we have to do in our import is to just call the notification module so module so that's supposed to come from the same package and then we're going to pass in the configuration so we're going to say with config and then pass in our custom configuration so i'm going to say custom configuration so we pass in our custom configuration we plug it in here as our import and then we're just gonna import the notify module so now we're gonna copy this and then uh export it here not import export so we're pretty much just putting this in the file is what i'm going to call this and then we're going to export it by that name which is the notification module which is this is the same thing we're doing here we say for our import we want to do all this work with this configuration and then export it we need to do an import so let me just copy this from the uh from the documentation we have to do this so we have to bring in those styles so i'm gonna copy this back to the app and we're gonna do another add import so at import and we don't need to do this because we already have the dependency in our nodes module we can just point to it like this okay so when you have this little we don't need this forward slash when you have this little tilde or whatever that's called and it's going to point to the nodes module so we import the style and now we have to do this one last thing i think um uh we have to do this okay so this notifier container we have to edit in some ui like html markup so let's go back to the app and close this and of course we only have this one html so we can just go in here and i'm just going to go ahead and scroll to the bottom of this and then just paste it here okay so that should get this working now we just have to test it and we can test this real quick just to make sure that it works so let's go and uh let's go and do this so i'm going to copy this line um back to the app i'm back in my main component and let's go up i'm going to do this a different way but i just want to show you that it's actually working i'm gonna paste this and make sure this is imported make sure it comes from angular under fire and we have to inject that in the constructor so copy this back to the app and we want to do this in the constructor so i'm gonna do private and just paste this in here okay so we inject this notification service so now uh let's look at the example let's look at a simple example because i don't want this complicated okay so let's look at this one i'm gonna copy this go back to the app and let's say after we get this response before we return we're gonna just print this notification out we don't have an id so i'm gonna remove this uh so we have to pass this to this service what if we do it that way so let's say uh let's just remove this line i think this should work as well so we inject it in here and then we call it down there so let's see yep there we go so you can see that it's working properly so i'm going to refresh this one more time and once the results come back you can see that we have the message here so we're going to create a service and then use the service instead instead of using their own service so let's go ahead and do that like i mentioned before we're going to turn this into our own service so we don't have to use it that way i mean it's still going to be injected but we're going to use it in our own way so i'm going to delete all this delete this guy remove that import as well all right and i want to create another service so let's go back here and in our service folder i'm going to copy this file and then just paste it here and i need to rename this to notification service so we're going to say notification service dot yes the first thing i want to do is to remove everything in here so select everything delete and remove all these imports that we probably won't be using and we need to rename this to notification service again we could use the cli to do this but i was being lazy now we're gonna actually do exactly what they said in the documentation so we're gonna create a private uh read-only and that's gonna be notifier and we're gonna give it a type of notification service so notification service uh it's actually notifier service notifier service okay so that's supposed to come from the library that we just installed now we need to create a constructor so constructor we're gonna pass in the notifier service so notifier service which is going to be of type notifier service and we need to do an assignment so we're going to say this dot notifier set it equal to the notifier service and it's supposed to be that one and this is misspelled this is supposed to be service notifier service and this should also be changed to notifier service okay so now what we want to do is to define some methods so i'm gonna say on default okay so i'm defining this method inside of this service and all it takes is a message which is gonna be a string okay so it's gonna take a message that's gonna be a string return type is void and then all we have to do is to call the notifier and then call notify and then we're going to pass in the default let's pass in the string for now so that's going to be the default and then we need to pass in the message and we already have the message so we're going to call the message another thing i want to do is to create an enum for the type of the message so that we can have this on a more clean way so i'm going to go outside of the class and i'm going to create an enum and i'm going to call it maybe type because it makes more sense and then i'm going to pass in the different types so the first one is default so default and we're going to set it equal to a string default so default and then i'm going to copy this again and then paste it and this time this is going to be the info so info and then change this to info paste it one more time this is going to be the success and then we have warning the last one is air change this to air so we have all of the different types that we can have so we can just use that type so i can say type paste it in here and then call the default and i'm going to put this on a little new line so you guys can see better all right so we have all the different enums here so now we can have a function for all the different types so i'm gonna copy this or just highlight it and do this and we want the on success so we're gonna say on success and just change the type to success uh do this one more time and let's call this on info and we just need to change the type again to info we're going to do this again and this is going to be on warning change the type again to warning and we're going to copy this one last time and then we're going to call this on air all right so i'm defining my own function and i'm calling the service so what we can do now is to just use this notification service inside of our class and all we have to do is to pass in the message we don't have to worry about this type or whatever because this implementation is gonna work so i'm gonna copy this name and i can pretty much close this i don't need to be here anymore and close all this and we need to go inside of the main component and we're just going to inject it here just like a regular service i'm going to say private and then pass it here and make sure you import this and i'm going to change this name to notifier okay so we're going to call this notifier so now all i have to do is to just call this notifier and then you know pass in on default or on air or something so after we got the successful response which is gonna happen here we're gonna say this that notifier and you can see that we have our own method so i'm gonna be using just the default and the air in case i get an error but feel free to use any one of these and you can also define your own because right now we're using our own service so you don't have to be stuck with the ones that you got from the from the library you can define your own but in my case i'm just going to use the default and then i'm going to pass in the message and remember the message is coming from the response so i'm going to say response.message there should be a message property on the response and i'm going to copy this and then go down so when we get an error as well remember this error is a string we can also show it to the user so i'm going to pass it here and then pass the error as my message because it's a string and then we're going to call on air so i'm going to copy this line and we're going to do this for all the other functions so scroll down we can do it anytime like maybe after this occurs then we can do this after we save the server then we can do this as well and when we filter we can pass in this message as well and when we delete we can pass in the same message all right whatever message we get from the backend is gonna be printed out here you can put it on this method here as well but you're gonna have to come up with a message if you want uh like we can do something like let's do report downloaded or something so that's up to you you can do it in any function in this class and then we're going to do the same for the air so let's just go up and we're going to copy this line and then we're going to do it for all the errors so whenever there's an error we want to show the air as well show you the air show the air and let's go down show the air here and we don't have an air well no it cannot happen here but we're not going to catch this error that way remember this is coming from a back in call so now i'm going to go ahead and go back to the app and if i for instance filter this you can see the message at the bottom every time i take an action the message is going to appear and if i try to print you can see the message report downloaded i'm gonna close that for now and if i ping the server for example paying success this is gonna be an error so let's see the error message bank fail you can see that the pink field is right there so everything is working as expected and feel free to go ahead and you know test this more but in my case that's gonna work for me i already know that it works but you can go ahead and you know look at it and understand the flow and then test it more there's a question that i think you might be asking yourself which is why would you try to build your application using the reactive approach when you can just use you know the procedural approach and everything would work fine well in addition to all the advantages of not having to subscribe and unsubscribe in the components you also have performance advantage so angular in the back end use something called a change detection strategy and by default it's going to use the check always strategy which is always going to be checking for changes in a component and then update the ui appropriately and what angular is doing is it's looking for every change in all your components for everything that is bound in the ui and then update everything appropriately in case there is a change in the component however when you use a reactive approach you have the option to use the unpushed strategy which is only going to look for change when there is an input change so if you're using the input and then there's a change on that property on the class or when you're using event emitters and then there's an event that is emitted or in our case when you're using observable and the observable emits so because we're only using observable and we're subscribing in the template or in the ui using the async pipe we can actually improve our entire application performance by using the unpushed change detection and i'm going to show you how we're going to do this right now so let's go back to the application and implement this strategy so we're going to scroll all the way up so you know that we can pass metadata in the add component and that's what we're going to do so we're going to go up here and then i'm going to put a comma and then go on a new line and then i'm going to type in change detection you can see it's coming up here and we're going to call the change detection strategy and then we're gonna change this to onpush what this is gonna do is it's gonna check for changes only when this component initialize so for example if i had a variable like name equal and then let's say i set this to junior right so whenever the component is initialized i have this name and i'm using it in the ui using you know string interpolation or whatever then it's gonna read this and say all right okay so this value is junior this is only gonna happen when the component initialize like the first time this component is loaded and then if somewhere down there i changed the value of this name so i do this that name equal and then i set it to a different string angular is not going to pick up this change because we only have the on push it's not going to look again for changes in the component and then update the ui it's only gonna do that for input for when an observable emits or when there is an event that emits some value and in our case we have observable so all of these well we don't have a whole lot of things we only have the entire application which is inside of this observable and then we have the filter observable and the loading observable and i didn't need to have those in this class i could have encapsulated them instead of this app data but i just decided to put these two in the actual component itself but i could have put these two properties inside of this object and then update it appropriately and then use the amp data so this guy and the component to manage this you know is loading and the filter status so we could do that as well that's another way you can actually tackle this but angular is not going to check for any variable that you set like this it's only going to check once when the component initialize and it's not going to check ever again so whenever you change this value even if it's bound in the ui it's not going to reflect and you can see that we don't have anything that we're changing here we have these two variables that were defined here we're not setting them to anything else anywhere else in this class right we're just defining them here so that we can use them nwi so we don't have anything defined like a typical variable like this we only have observables so because observables are gonna you know push changes and the on push is gonna detect those and it's gonna update the ui accordingly so if we go to the application right now we're not gonna see like any difference because you know the performance improvement for this little application is probably minimal like you probably won't even be able to detect it but that's a little bit more of an advanced topic more advanced things that you can do with angular when you're building your application so you can take advantage of these little things uh right now this is small like it doesn't even matter but when the application is very large and the default so if i type in d you can see the default here and if we go in there you can see the default is always checking so it has a check always strategy so it's constantly watching every variable that you set equal to something here that you change either here or in some other component and it's watching for those changes so the library is working really hard to keep track of all these changes but when we change it to onpush remember it's only going to check for input changes when an event emit or when there is an observable that emits which is what we're doing here so this is definitely gonna improve our our performance and that's why i wanted to show you an example where you can do that in your application so now if we go back to the ui everything should be the same like everything will work nothing's going to be broken because we're binding these values to the component using observable we're not using like typical variable declaration and you can go ahead and test everything else should work as well we can still ping or we can delete everything will work so that's pretty much everything that i had for this course and again if you have any questions or something is not clear you know go ahead and reach out to me i'll be glad to help you and you might not want to do this every single time like for this application for example like i didn't really have to do it that way but if this application were to grow then you would see how this approach would be very very helpful when the application gets really complex but in a lot of cases you don't really have to do this because your application is not gonna you know have any complexities in it performance is really not something that you should worry about so probably this approach is not something that you want to kill yourself to do but it's a little bit of a more advanced way of coding with angular and the guys at google's and the big companies that's how they create all this fancy application like gmail and stuff so that's how these applications are built they're built in a very smooth and performance aware way because those applications have really really heavy loads and again like i said you might not want to do that every single time when you're building a little application but it's a very very interesting way or a very interesting approach to take when you're building your application and again if you have any question reach out to me i'd be happy to help you and i'll see you guys in the next one okey dokie if you manage to stick till the end i want to thank you so much for sticking around give me a thumbs up so i can keep on providing you content like this also if you're not part of the amigos code community both facebook and discord go ahead and join the community's massive and if you haven't subscribed to junior's channel go ahead and subscribe show some love and so for now i'll catch you on the next one you
Info
Channel: Amigoscode
Views: 57,222
Rating: undefined out of 5
Keywords: amigoscode, java tutorial, spring boot tutorial, angular tutorial, learn java, spring boot microservices, spring boot full stack project, spring boot full tutorial, spring boot full course, angular and spring boot project, angular and spring boot application example, angular and spring boot, spring boot api, typescript, backend development tutorial, mysql
Id: 8ZPsZBcue50
Channel Id: undefined
Length: 226min 33sec (13593 seconds)
Published: Mon Oct 25 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.