Loading
Lesson 17
Courses / Build a Web App like Twitter from Scratch Using HTML, CSS, JavaScript, Express, MySQL
Making an Express Route to Create the Resource and Fixing the Frontend JavaScript

Video Transcript

Welcome back to another lesson. Now let's get back to the development of our API. So I have npm run that here it's running the server with no mod now let's get back here to server.js and I'm gonna remove the hello that I had added before. Now we have this endpoint to get all the entries but notice as I add a manual entry and I keep adding entries if I restart see what happens it's all gone and you can see this is happening because every time we hit the route it's creating a whole new array every time and it's it's regenerating the entries so it's not really persisting at least in memory so let's change this a little bit so we can persist those in memory. So what I'm gonna do is I'm gonna cut this entries array out of the route handler function and into the global scope of the script that way entries will only be defined once and we'll have these three. Now that's nice but as we add something new and we refresh it's all gone and that's because we're actually not even hitting the server to add a new entry. You can see as you click the network tab and you type something and click right no new network requests appear right so we need to make a new network request to the server and asking the server please create this new entry and the server can say okay fine or it can reject with an error message perhaps you had sent an empty message or some very very long message that the server refuses to accept and that's called validation right in any case let's get back to what we're doing let's take a look at the client side script.js when we click write what does what what happens remember that we had added an event click event to the submit button every time you click that it's it's grabbing that the value that was typed in the text area then it's checking for errors validation right and finally it's calling add new entry but when it calls add new entry all it does is adds it adds a new entry to the page but actually it didn't call it we need it didn't call the server so we need to do a name between here so before we actually add anything to the page we need to first make a request to the server. So how are we going to do it? Well we're gonna follow the same approach we did in FATCH entries except it's going to be an entry to create not to obtain what's ready in the list of entries. So let's create a new function here I'm gonna call function create entry okay the function create entry will be responsible for making a request to the server. So let's do it. Well how can make requests to the server use FATCH? Now FATCH takes one the first argument is the where is it right so what's the URL we're gonna say HTTP colon slash local host colon 3000 that's where our server is listening and we're gonna say slash entries in this case it's a bit different because because it's going to be what's called a post request instead of get so because of this special case I'm gonna add a second argument to FATCH and that is going to be the argument for options and in the options I'm gonna say the method is post so I pass as a second argument to FATCH an object this object has the property method that has the value post so that when it makes the request it will be a post request instead of get okay that's the first step now you need to send something right and that's the text that you typed how can we get that let's take that as an argument to the function create entry actually let's do the following let's say entry as an object let's assume entry is an object entry is an object like this has a text property with the value of what it was typed there okay now we have to take that entry and we have to to convert that object to a string and that string will have the format JSON that way the server can interpret your request properly because this is our server is what's called a back-end API that serves JSON format it accepts JSON it produces JSON as output to you so to do that let's add a new property to the fiat options given to FATCH let's call it body and that's going to be the entry except we need to convert it to JSON to do that we can use the module called JSON or object JSON and there's a method called string if I and you call that with whatever you want to string a fight in this case will be the object entry so this will become some text with the format JSON it's almost the same thing except the keys will now have quotes in closing the the value text right so this would become like this to add here to the JSON format let's also add some headers just in case usually you want to add the content type application JSON header so here at the end one more option called headers for this request and the key will be the name of the header content type and the value of the application slash JSON let me use double quotes to be consistent with our code it doesn't matter in this case you can use double single quotes choose a style okay I've got a comma just style so FATCH okay great FATCH slash entries and its method post here's the entry for example it could be like this and headers it's just saying this is content type of the body right the body is to be interpreted as application slash JSON format so we're gonna make that request to the server let's let's see what the server says let's go back to server.js and you know you know notice we have app get entries but we don't have posts so we have to add app.post slash entries and add a new route handler rec res anonymous function here so let's just do a console log here of whatever let's say the request object I don't know there might be a lot of stuff in there let's just see what that is and then I'm gonna send something back I'm gonna say okay 200 something like that just so we have some response from the server now you can see no mon already restarted my server so I don't have to do it manually now let's go here and back to script.js I didn't call this yet right let's make sure to call it every time you click right and pass the validation right add new entry well we cannot add it just yet let me just comment that out and say create entry and I'm gonna say a new object with the property text and that's going to be the entry text so I'm passing an object that I just created an inline literal with the property text that's the entry text whatever we typed in the text area let's try it out refresh your page type something let's type hello world actually click right watch the network tab of the browser you can see there's a new request let's click on that request method is both correct we got 200 okay notice the request headers here has content type application JSON that's what we wrote what we said notice the payload is what we're sending and you can click build a source here and it's exactly what we had there so it's the it's the entry right object in JSON format notice the double quotes and closing the text key now let's see the response from the server okay 200 that's fine now let's take a look at the terminal because the server is running here and if you do a console log from the server side it's gonna appear in the terminal so it's a lot of stuff and this is the this is the request right object and that's a lot of stuff in here but let's see let's start from the beginning if we can find the beginning there you go the incoming message other stuff readable let's see if we can find something that we recognize I think it saw something before something about the body maybe I don't know or maybe it's in a buffer format or some sort I don't know here's the headers let's see if we can find content type here this is what we set in the client so it's appearing here the server received that that's great route path and so on so so we're getting something from server side so that's great so let's continue now so from the server side what we're gonna do is following given we have this array here called entries how about we add to the end of the array every time you call post entries that makes sense right let's do it remove the console log and let's say entries dot push whatever the new entry is right we don't have it yet but let's assume we had it so entries dot push whatever and then usually when you create if you follow rest rest what's called rest convention rest for API convention if you want to create a resource like a post slash resource name usually you send back the created resource and that created resource includes the ID that was generated from the database okay so let's send back the new entry let's say I'm typing the wrong he sorry let's say that new entry somehow add an ID and that ID let's say just to simulate simulate the database let's take the length of the entry because it kind of let me see the first one is ID 1 and 2 and 3 if you take the length of entry plus 1 that's gonna be the new available ID right the next record of BID 4 that's an available identifier no one has that yet but let's do that let's do entries dot length that that gives you three right now initially and you add one of very four so ID 4 and I need of course I need to say what is the text right that's gonna be come from somewhere and that's somewhere it was was given by the client to the body right but we don't know how to access that yet right so let's try something what if somehow the request had the body and we could just reference like this it'll be very convenient right let's do a console log rack body colon rack dot body it'll be undefined right now and that would be actually dot text because right the body would be an object and later on we can do a refactor use dot store pool dot we're gonna teach you how to do that later so we create the new entry push that and if finally we send that new entry back to the client and the console log is just for debugging let's take a look I mean write something right something happened here oh no not read property text I'm gonna find that makes sense go back to the server you can see rack body is undefined but how can we define it well we're gonna have to download a third-party module could be something like body parser I go to express let me see if they have in the express website let me search for body parser something let's see if they mentioned anything here body parser yeah there's a body parser middleware body parser take a look here there you go so here's the module we want body parser and we can just after use body parser like this so it's a middleware that will do the following since our client is sending the record right the new record to be created in the JSON format the server has to take that a message and convert it as well back into take that JSON convert it back to a JavaScript object so it can use natively through Node.js right mean it doesn't know what to do with the text itself but it takes that text and parses it and it creates an object JavaScript object with the information from that text okay JSON formatted text so we can do it like this body parser.json so we already knew learn how to apply a middleware right something that comes in between the request and the ultimate response let's go here let's first install body parser so I'm gonna kill the server I'm gonna say npm install I'm gonna call it its body dash parser fine now you can see body parser is under the dependencies I'm using 1.19.0 here now go back to the server and you see you have the course middleware we're gonna add the body parser app.use body parser.json call it like this now this has to be imported I'm gonna go here at the beginning I'm gonna add const body parser in camel case require body dash parser. Let me call it at the end my style so we call it here too is my style now with that there's no every time you get a request it's gonna pass through the body parser middleware and it's gonna automatically convert the JSON string into an actual JavaScript object with that it's going to set the rec.body property with that object now let's restart the server here at PMRoundDev and let's go back to our site and reload and I'm gonna do I didn't have to reload that I'm gonna add right you can see in the console log here now rec.body is defined and it's an object whose key is stacked and this is the text looking here at the row in the browser you can see that the response that we get let me see response the raw response is the actually created the new entry and you can see the new ID here ID for was added as well and of course this is not the browser likes if you click the preview tab it the browser will automatically make this look nicer to you but the actual response is the one liner like that very nice now going back to the text editor server.js I'm gonna do this with factory to spread so let's say that your request had many many properties so you would you could type one by one like this rec.body ASD whatever and keep doing that right let me but I'll be tedious one other way you can do that is like this you can say dot dot dot rec.body what this does is it copies all the properties from the object rec.body and adds it in to this new object now mind you there's a you have to be careful here because the client could be somebody else who's trying to do something bad in your system so the client could add in some extra properties in there or perhaps your client we're not giving all the necessary properties even though it could bypass the client side validation mind you client side validation is not safe at all anybody can bypass that so you have to make sure to have validation on the server side okay so what I would advise here is you have to have some way of first filter accepted or properties okay say the the client gives you like text whatever but also says something else here something else here you don't want all this extra stuff maybe it's a malicious client trying to do something bad so you want to make sure to eliminate that before you do anything else and even pass this to even a database to try to create a new record so you want to filter the accepted properties that's something I leave it as an exercise for you to do find a way to go to the object and only take the properties that you want of course what we had before works just fine right and that's actually a good way of filtering it like this that way only captures the text and everything else is discarded right so I'll leave it like this I'll leave it as an exercise for you to figure out a way to do that you could make some sort of system that's nice that you can make like accepted properties is some array like text whatever and then you can loop through it and generate a new object that excludes all the other undesired or invalid properties something like that you can you make a new function okay make a new field there a helper function for example filter I don't know filter entry properties or whatever what do you want to call it exercise for you okay let's go back here to the client side I'm gonna refresh the page let's see if this is actually doing anything you can see as a type and click right even though it's not appearing in a client side on the DOM right the document object model it the request is made if I refresh it appears magically because when you make a request to the server to get all the entries that those array of that array of entries is in memory right since I didn't restart the server yet because I didn't make any change just now it still keeps that in memory mind you that every time you make a change everything would be out wiped out in the server side because the everything will be reloaded and restarted so it'll go back to the original state but as long as I don't restart the server it will persist at least in memory of course that's not ideal right because you could restart the server many times throughout the history you don't want to lose your data you don't want to keep your data all in memory that's really bad what you want to do is store that in a persistent data storage and that's a you can use a database right and that's eventually going to store your data in the hard disk hard drive not in the computer memory because computer memory is volatile it can come and go frequently so that's nice well let's get back to the script and flex fix the client side we have the create entry here but we want to make sure that it adds a new entry well of course I could sequentially do this but that's not good why because of the a synchronized nature of JavaScript here and also of the request response model right because when you say create entry here you're calling this function this function will call fetch but then it will continue execution of the program and immediately after it will add new entry it probably would add a new entry even before you got a response from the server so to illustrate the point I can do the following let me see I can set a time out here and let's do this so I'm placing the fetch under timeout meaning that after a certain number of milliseconds I want let me put five five seconds is five thousand milliseconds after five seconds it's going to execute the fetch so it's going to delay it by five seconds and because of the synchronized nature it's going to call create entry and immediately after it's going to add a new enter even though the server did not fulfill our request let's try it out so I'm going to click right you can see no request but it was added already you can see no request in the network tab and finally after five seconds the request is here and the server said okay I created a new entry so this is not good at all right we have to wait for the request to be fulfilled that is you make the client makes the request to the server this and that might take some time right to reach the server and then for the server to process your request and finally for the server to send back some response and that takes time because of that it's a synchronous asynchronous so there's some time you have to wait and we cannot just do things like this so in order to add a new entry here we have first to wait for the create entry that request to be fulfilled and successful before you can add a new entry okay so how can we do that well I'm gonna do that through promises this is called the concept of promises right we already handle promises in the dot then here and dot then here so let's try it out they'll do it the following let me remove the time out here do I remove it yeah I'm gonna remove it right now I just wanted to illustrate the point of delaying so fat is actually returning a promise when you call it so after that promise we want to do something right so usually want to do a dot then and that's gonna give you a response and that response we need to extract right while we got back usually eyes the created entry with the ID so I'm gonna grab that even though we already know what we typed I'm just gonna grab that because the server included the ID so I'm gonna take and return response that Jason right remember we did that here before we need to convert that into a JavaScript object okay and finally we're gonna get the entry and what we're gonna do with the entry is gonna append right here and let's see what we can do here I I could move this at entry here but now that I'm thinking about these things again I actually want to separate them because I want to make create entry have only the concern of making a request to the server and that's it and I want to separate that from the actual manipulation of the document here so I'm gonna return here the fetch meaning the function create entry will return whatever this operation does in this case returns let's see fetch returns a promise and then a do dot then to handle that promise and from that you return response that Jason who which by itself is also a promise right so this is gonna return a promise and we can use the same dot then outside when you call this to handle what's gonna happen after the promise has been successful right so let's go back here to create entry this returns a promise so I can chain a dot then right and that returns what that's gonna give me the entry as the are the parameter and we can use that actually to call add new entry here in this anonymous callback function and instead of entry text I want to say entry dot text and actually later on if I wanted to I could include the whole thing that would have the ID and everything but since I'm not using that I'll just let it be because that we're keeping it simple simple right now so this returns a promise that is handled with the dot then so after this is successful we got a response from the server and we converted that response to an actual JavaScript object so we can work with this JavaScript object appears here in the callback as an argument entry and you can call add a new entry entry dot text if you want to get set a breakpoint here if you were just curious about what this is about so I'm gonna go to the browser go to sources script.js find the block that contains that new entry and click line 55 here to click the number and you can get a blade point in this red circle you can type something click right now after calling create entry you can see there's a network request here for it was successful and finally we are at this point line 55 and you can hover over entry you can see actually that's actually the thing that was created right from the server side and if you see entry dot text is whatever we typed and that's great it's been passed by a new entry which will create a new entry into DOM and click resume here and it's here now successfully after the server accepted it that's great now what happens if the server was down we simulated some sort of error let's see click the terminal kill your server now try to add something again click right something happened post error connection refuse fail to fetch well the user didn't know what happened so that's something we have to fix you can see the request fail to low response data so where what happened let's see so where is it making the request right here notice that this could fail but we did not handle the failure how could we handle the failure we can use a catch block so let's think about it here create entry if this failed you could catch it here for example that would be one way and the argument be the error oops I've been the wrong key let's console log that and let's go here can I even put a breakpoint there to see that it's actually going there as we restart and I'm gonna pull a break point in create entry catch and we remove that other one I click here to deactivate the breakpoint on line 55 I'm gonna type something right you can see it goes there it tries to make the request it fails because it fails instead of going to the dot then it goes to the catch okay so if this promise is if this tries to make something this promise is rejected with an error and because of that it goes to the catch block and it skips everything every single day and after in between them so I'm have the error here you can hover over it and let's console log it you can click F8 or press F8 or click that you can see we got log type error failed to catch so you can use that to show error message here let's try it out remember how we did error messages we did a validation remember on lot lines 50 through 55 we have an actual new entry our element that we add the class actually remove the class to what make it appear something like that let's take a look in the dome here if I click in here there is something hidden you can make it show with this checkbox here you need to type at least one character of course the text would be wrong for this new type of error so my you want to change the text content of that let's let's check it out so we could we could do that here or we could change the concern and let the caller handle the error let's do that so instead of doing the catch here I'll let whoever calls create entry to be the handler of the error so here in I have the dot then if anything happens I'm gonna put a dot catch and we're gonna do the error thing so I'm gonna target the error span as you could actually do the same thing over again copy this code since the variable is in scope here I probably could use it again but why don't want to refactor this later because I don't want to tie B2 depending on things that are have different concerns but it's fine let's do error span that grabs the the remember that spend with error that's hidden and what I'm gonna do is I'm gonna change the text content to be whatever error the message we got so error has a property called message because it's a type error or whatever error error usually has a type a message property in JavaScript error object and I'm gonna say error span the class list dot remove new entry error hidden class so it can appear I'm assuming the error exists so you might want to add a guard here in case it doesn't exist but I'm assuming it exists but we got to be careful we should make maybe add an if statement here otherwise if there there is anything there is gonna create an error right it's gonna error out let's refresh and okay type something you can see now fail to fascist here okay now the user knows what happened so we changed the text and we made it up here if I rerun my server let's do and now servers back and I try to add something now it's working okay I you notice that the entries let me remove other break points remove all and if I kill the server and I restart you can see the user doesn't know what happened so I want you to as an exercise add an error message here saying like whatever could be that same message so the user knows that the server is down or it could not fetch the entries so that would be whoever calls fetch entries right here you want to add a catch block dot catch and then you're gonna do the same thing similar thing that we did here you're gonna change the you want to maybe you want to create a new a new area of the page for the error or you could use the same error that we had here I probably would use the I would do the way I would do it is I would actually make a new element for the error that's related to the actual list because I cut when I think about the user interface elements or components this text area with the button is something separate from the list itself so the list itself should have its own error message it should have its own error and that's separate separated from the error related to the actual text area to the submission of the text okay so that's an exercise for you let me see if I can add here somewhere where's the fetch exercise dot catch error here do whatever this is a multi-line comment you know there's slash slash for single line and there's this slash star and star slash everything in between is a comment when will be ignored okay let's summarize and go over what we did so far let's see if the server is running let me restart the server now so we added a new route to create a new entry on the server side and when we type here click right and actually make so request to the server and the server here on has a new route that's post let me remove the console log we don't need it anymore it creates a new entry takes a new ID that is available and includes that in the new entry takes the reactive body the text reactive body is is set by body parser a middleware that we used it's the npm package body-parse require it and then you can use it up here and every time the request comes that text in JSON format will be converted be parsed into an extra JavaScript object that's easy to work with and that object is available in rack dot body we took the text from that object and created the entry and pushed to the array that's in memory for now we don't have a database yet this is just for us to have something to work with and that was added to the end of entries so that will persist as long as the servers is running was not restarted right if I had something and refresh still there that's very nice so we fixed the front end to because it was not doing it was always adding something even though the server did not approve it beforehand so we have created entry that makes a request HTTP request after that if everything successful we go to the then and actually add that to the document in the page if there is any errors we do a dot catch block here and remove this extra to be cool and we show the message that in that next to the right button as an exercise left for you to catch the error that might occur if when you fetch the interest for the first time as you reload the page I suggest you kill your server and restart the app to make simulate some sort of error with that for that's it for this lesson I hope to see you next time have a good one
No comments yet (loading...)
No comments yet (loading...)
Did you like the lesson? 😆👍
Consider a donation to support our work: