Lesson 16
Building a backend in Express.js for a React.js app [raw] - Software School (2024-04-16)
Video Transcript
Okay, so today we'll add a back end to a React application that we built previously.
And here's the repository and make sure to download this code or clone it.
Now I'm going to click this file for the wireframe to refresh your mind about what the app is
doing.
It's basically a box full of text that's pretty much like a message board or a chat room.
And then at the bottom we have like an input type text where you can type anything, click send,
and it will add to this list.
Now the list of these messages are initially fetched from a back end, but it wasn't the
back end that we built, it was just for somewhere else.
But today we're going to learn how to build, actually build that back end.
So we'll leverage React obviously for the front end that's already written in that repository.
Then we'll use Node.js that is JavaScript on the server side so that we can build a
back end API that serves JSON.
Now we'll use the Express library that makes it easier for us to work with Node.js and
HTTP servers.
Here's the website that you're interested in.
Like I said before, we need Node.js installed to your machine, the text added to your choice
like Visual Studio Code.
And you're going to need to open a terminal, for example Linux, just click the terminal
and look for terminal.
Mac the same way, look for terminal or click the terminal icon.
And then on Windows you can use Command Prompt or PowerShell.
Okay.
So let's get started here.
Let me share my terminal.
But before that, just look at Visual Studio Code first.
Let's refresh our minds.
So we have a project with package.json, so it's NPM project.
You can see we're using these React scripts to load the React app in null.
Now I'm going to add some dependencies here for the back end.
So usually maybe in the real world we'd have separate repositories.
One for the back end server, one for the front end server.
I put the purposes of keeping this class pretty convenient, everything in the same place.
So I'll just add the server to the same project.
Okay so let's go to the terminal and install Express.
So make sure to cd or change the directory to the project directory.
You can see if you ls or dir, all the files are there.
So we're going to NPM, space, install, space, express, enter.
NPM is the node package manager, it allows us to install third party dependencies.
That is code that's written by somebody else and that they make it available as open source
for us to consume and use in our own project.
So we don't have to write everything from scratch.
It might take some time to install Express.
Okay, we have installed.
Let's go back to Visual Studio Code to verify that our package.json file indeed added Express
under the dependencies property here and you can see it's version 4.19.2.
Now you can also for the verify that we installed Express by looking at the load modules directory
and you can see there should be an express directory there.
Scroll down, there's so many dependencies.
There we go here, this one.
So basically when we use Express we're taking code from this directory in any case.
Let's go here and make a new file called server.js.
Actually let me make a new folder as well, so we put everything for the server in one place.
So I'll move server.js to server and I'll rename server maybe to just index.js.
Now let's write the code to just jump start a server back in server.
We're just going to require Express like this.
Put that in a variable, we just call it Express, same name as the module.
Now we could take that Express and call it as a function to create what's called an app.
If you want to add semicolons, if you like, it's optional.
It depends on your JavaScript style.
Now I can put that in a variable that we call typically APP or APP.
Finally we can say call the function from this app object that's called listen.
And then you just have to say the port you want to listen to, for example 3000.
I'm going to save that.
Okay, is it too much for you to describe the hotkeys as you use them?
Which hotkey?
Okay.
Now let's try this out.
I can actually open a terminal within Visual Studio Code,
but if you want to do it in a separate terminal that you have opened, that's fine as well.
So I'm going to press control back tick usually or to open the terminal here.
If you don't see that, you can just click view and terminal if you're using Visual Studio Code.
If you're not, just make sure to go in your terminal here and type the commands there.
Set, okay.
But for convenience, I'll keep it in Visual Studio Code so we can see better.
Anyway, let's CD the server directory.
And then I'm going to say node space index.js.
So it executes this program index.js.
Now you might have noticed nothing is happening, but it's actually running the server.
So if you want to kill the server, you press control C, that's to send the interrupt signal.
And you can see the prompt is back here again.
Okay, so control C to interrupt.
So if we go to the browser to verify that it's working, I can open a new tab and say localhost colon 3000.
3000 is the port.
That's the argument we pass to the lesson function.
You should see cannot get slash.
That means it's working.
That's just expressed telling us, hey, we don't have this endpoint or route defined.
So it arrows out that way.
Okay, great.
Going back to Visual Studio Code.
Let's add some feedback so we know the server is actually working.
So the second argument to this lesson function.
I will pass a callback function.
Let's add a function here.
So definition of a function.
And then we're going to say, oh, let me change my spaces here to two indentation.
So when I press stab, I add two spaces.
I like two spaces.
If you don't like that, you choose whatever you want.
So I'm going to say console dot log.
So console is an object we can use the log function to print something to the terminal.
Terminal is what's called the console.
So let's say server is running at htp colon slash slash localhost colon 3000.
I say that save the file.
If you want to save the file, if you don't know how you can click file save or you can do control s if you're using visual studio code.
Anyway, going back to the terminal, control C to quit.
And I have to run the same thing again.
I usually press the up arrow in my keyboard to go to the previously typed command and I press enter.
Now, why did I kill the server and started again because I changed the code?
Every time you make a change to the code.
You have to kill the server with control C and then restart it typing the same command again.
Now we can see there's a message server is running at localhost 3000.
So that's better because now we know that something is happening.
And it even highlights this URL.
And if you hold control in your keyboard and click, it will follow the link.
That means it will open the browser conveniently for you.
Okay, that's nice.
So we got it set up, but how does it tie to our react application?
Well, let's go back to react.
Now, if you remember, react application was defined source.
And then we have this app.js and so on.
Now let's run the front end.
Now to run the front end, we're going to need a separate terminal window or tab.
It's up to you which one you're going to choose.
So if you're using a standalone terminal, you can usually the hot key is either if you're a Mac command T,
or you can click the, let me show you.
There's probably a plus sign up there in the tabs that you can click to open a new one in the same window.
So you want to do that so that we have two separate windows, one for the backend server and then one for the front end.
Now, since I'm working with Visual Studio Code, the built-in terminal, I can also do it there.
So in this case, I would just press this plus here or the Chevron to choose what kind of terminal I want to open.
For example, a new command prompt.
I would see now some tabs here on the sidebar.
I can go to the node one, which is the backend server.
I can go to the other CMD that I opened just for the front end.
Now to run the front end, make sure I am in the root directory of this depository, meaning further introduction to React.
I'm going to run a PM space start.
And that should run react script start.
It should take some time for the front end to open.
I think this one will automatically open the browser window with the React application.
Oh, it's detecting that I used 3000 for the backend.
Would you like to run another port?
So what we can do here is either accept this, or maybe I'm going to press Ctrl C to finish that.
Then I'm going to go back to the backend code here, server slash index or JS.
Instead of being 3000, I'm going to choose 3001 so it doesn't conflict with the same port as the front end.
Okay, I'm going to save that, go back to the backend, make sure I kill the server and run it again.
Now it's going to run in 3001, the port.
Okay, now with that problem solved, going back to the other terminal instance,
for the front end, I'm going to MPM start again.
There should be no more conflict now.
But this one will use the port 3000.
So we got localhost colon 3000 for the front end and localhost colon 3001 for the backend.
Okay.
Let's see in the browser, open in your tab, localhost 3000.
What is going on here?
I'll cut time errors.
Assignment to undeclare variable titles.
There's some error going on here.
Oh, okay.
Yeah, so there's an error in the code.
Let's fix that.
No problem.
So if you notice, I open the dev tools to debug this.
I press F12 in the keyboard.
If you cannot press F12, right click anywhere, press click inspect.
It should open the dev tools here.
Now what I did, I went to the console tab of the dev tools,
so I can see this error message, uncaught reference error, whatever.
I can actually click the source code name, file name,
so that it goes to exactly where the error occurred.
So I know, oh, okay, I didn't declare this variable with the const keyword.
That's probably why that's happening.
So let's try it again.
Going to the Visual Studio Code, app.js, the line with titles.
I think I maybe just need to add const here,
because that's the syntax required for JavaScript.
Let's try again going to the browser.
And now I can see the data was fetched correctly.
And if I open dev tools with F12 and click the console tab,
let me click the trash so it doesn't see stuff and refresh.
So we don't have that problem anymore.
Now there's this warning here about reactage,
child enlisted to have a unique key prop.
Now this typically happens when you do a mapping
and you're generating components dynamically.
It's not really a problem per se,
but it always requires us to specify a unique key prop.
We can also fix that warning going back to Visual Studio Code.
So we got to go to the component app where it's rendering.
That is the return value.
We have some JSX here.
So I'm doing some mapping somewhere.
Okay, it's line 31.
I'm generating these divs with the message dynamically with the map.
So all we have to do is, okay, this generated div,
we have to add a prop called key.
And the value must be something that's unique for each of these different elements.
Typically it's the ID of the record.
I don't know if we have an ID for this message,
so I'll just put the message itself there.
Other people also do add a second argument to this callback
called the index of the array and place it here.
But there's a downside to that.
And it's because if this list is sorted, it might cause some problems.
But we know this is not a sorted list.
So it should be okay if you do it that way.
Okay, let's go back to the browser and refresh.
Now I see no more problems in the console here.
Okay, now this data here for these messages,
we want to be able to build our own back end to serve that data.
So that's what we're going to do next.
Now if we go to...
Let me first tell you how to debug,
how to understand where this data is coming from.
With the dev tools, press F12 again,
and you're going to see the network tab in the dev tools.
So you're going to refresh the browser.
And we're going to see...
Let me see, there's some filters here.
If I click all, that's everything that was...
Every request that was made.
So this one I know it's a XML HTTP request.
That's typically what we use these days
when we fetch some data from a back end API that serves JSON format.
So I'm going to choose XHR filter.
So I can see here it's fetching data.
And I can click one of these requests to see more information about it here on the side.
I can want to look at the response.
And you can see if I click raw, this is the raw thing.
And that's where all this data is coming from.
Now, this is a back end that somebody else wrote
in JSON placeholder.tipicode.com slash post.
But we want to build our own instead of using this one.
So if I open a new tab and you go to that,
you're going to see all this data and you click the raw.
It's just text with JSON format.
So let's copy this data, actually.
I'm going to copy a bunch of records, at least 10, okay?
Let's copy at least 10 of them.
You don't have to copy them all, but that's okay if you copy them all.
I'm going to control C to copy.
And then I'm going to go to Visual Studio Code.
And then under the server directory, I'll create a file.
Let's call it post.json.
And I'm going to paste that data here.
Now, let me choose spaces two here because I like two spaces.
And I'm going to paste it again.
Now, make sure to close the array at the end
if you don't have the closing square bracket.
And this lingering comma should not be there
because it's JSON format.
Be careful of the lingering comma in the last object
before the square brackets closing.
And I think this is a properly formatted JSON.
So I saved this file.
Now, today we're not going to use a database
because that would be too much for us to do.
So we can kind of simulate a database
by just storing the data in a file like this, post.json.
So if we want to manipulate this kind of file database,
we just got to modify this file and overwrite it.
Okay, so we got the data.
Now we have to find a way to serve this data from our backend.
Now, if you go to index.js for the server directory,
we don't have any route yet.
So route, you can think of a backend as a server
that if you ask for some resource,
it will give you back that resource.
Now, we must define all these pathways
of getting a specific resource.
And this is the pathway for the posts.
So typically, when you want to obtain information,
you make a GET request
and to some endpoint that I can say slash post.
Now, this GET is the method of the HTTP request.
HTTP hypertext transfer protocol
is what's used to transfer the data from the server to the client.
Now, this protocol has a method that's GET
that's typically used to get information.
There are other methods like post
that's usually used to post information.
That is, for example, you're creating a comment on a website.
You need to give the comment content, right?
What did you write?
That's why you want to post that.
But anyway, the second part is the endpoint URL.
We're going to do slash post.
And this kind of way of writing the endpoint is called, like, RESTful.
If you ever hear about that, you can look it up on your own.
But basically, if you want to follow the REST way,
there are many resources like posts, you know,
like comments, products, orders, and so on.
So each of them will have their own kind of endpoint.
So we have slash products.
We have slash orders, slash whatever resource it is.
And this one, the resource is just post, so we call it slash post.
And notice it uses plural.
Some people might use singular, so it's up to you.
If you want to say slash post or slash post, I usually use plural.
Okay, but you can give any name you want.
Okay, any path you want.
But this is just a convention that's called REST.
In any case, let's make this endpoint.
So to make an endpoint before the app.listen, we're going to say app.
And the function to call here is actually the name of the method get.
If it were first, you'd say post, but we're doing get.
So dot get and then call it as a function.
Now we need to say, okay, get what slash post as a string.
So that's the path.
Now the second argument is a function with two arguments, rec and res.
Now this is a callback function that when we ask the server for this,
if we make a HTTP request to get slash posts, it will end up calling this function in the end.
And you have access to the request object and to the response object.
Okay, that's why we call it rec and res.
Now these variables, you can call it whatever you want.
This is just like a convention that people use in a short,
but choose whatever you think is appropriate.
Okay, so the data is post.json.
But first we need to read that a very easy way to read a JSON file into JavaScript or Node.js is with require.
So actually you can just go up here and say require now dot slash post.json.
Now the dot means current directory and get slash is because we want to get something from the current directory and the file post.json.
Now when we do this, we're going to load all this data from this file into an object in JavaScript.
Now because this object is an array, we can just call it const posts like this.
So store this in a variable that I called posts.
So I can conveniently use this here to send a response.
Now to send a response from the callback function here or handler,
we have to use the res object.
Remember that's the parameter here and then call the function dot send with whatever you want to send back to the client.
In this case, I want to send back the content of this variable post, which is just an array of objects.
Now I'm going to save that and to test this out.
Remember, if you make a change to the code, you have to restart the server.
So I go back to the back end here and I'm going to kill the server control C and then run it again with node space index dot js.
Now with that, I want to test this out to see if it's really working.
So I go to the browser and I'm going to open a new tab.
So actually, when you type an address here in the browser, localhost colon 3001 slash posts, it always makes a get request.
So your browser itself is always making get requests every time you type something in the address bar and press enter.
If I do that, you're going to see the response.
I'm going to click raw data because I think Firefox is formatting that.
So this is the raw response is just text in the JSON format.
That's pretty much the content of that file.
Now this is the raw thing.
You can click pretty print of Firefox.
I don't know if your browser has this function.
So it kind of formats in an easy way.
And I think it also does this live format to make it easier for us to visualize, but it's just text.
Now let me see the headers here for this response.
Response header.
So in HTTP, we have a request and we have a response.
So the client, the browser, we make a request and it will include some information in that request.
And some of that information is starting what we call the headers.
Headers just pretty much a set of pair and values, right?
We have the connection header with the value keep alive, content length header with the value 6, 0, 6 seconds, so on.
So just metadata about this request, you know.
So the response can also send headers the same way.
So this one is the response headers and the one in the bottom here is the request headers.
Now I'm using Firefox and it shows this conveniently.
So if you're using another browser, you might not have this.
So how can you see that?
I can press the F12 to see the DAV tools, click the network tab and then refresh and you should see the request down here.
I probably have to click all here now.
All filter and I click this first one and I can see here the response headers and I can collapse and the request headers there.
Now you can see the request, no payload and then response all of this if I click raw is just text.
How is everybody doing so far? Any questions?
Oh, good.
Okay.
All right. So one thing I want to touch upon is setting a header because typically when we send a response,
we want to make sure to let the browser know the client what kind of response we're sending.
In this case, it's a JSON.
It could be HTML page or just plain text.
So let's do that next.
So going back to Visual Studio Code, before I send the posts, I can modify this response.
I can actually change headers if I want to add additional information about this response.
And the additional information I want to add here before I send is that I want to say this is JSON.
I'm sending you some JSON content.
So we're going to call the res object dot set.
We want to set a header, a response header.
Now this function takes two arguments.
The first is the name of the header.
Content dash type is the one that we can specify the type of information we're sending back to the client.
Call out the value for this.
The value here would be application slash JSON.
This is just a standard, what we call MIME type.
This is just the way everybody agreed to write if we ever send JSON back.
Application slash JSON.
If I save that, go to my node server, kill that, restart.
Verify in the browser again.
If I click refresh in localhost 3001 slash post.
I should see here in the response headers, I should see content type application slash JSON there.
I don't know if you can see.
Make it bigger.
It's right here now.
See this content type.
That's what we set in the value application slash JSON.
And there's some other stuff here I think Express adds the character set UTF-8.
That's for Unicode.
And if I click raw data, pretty much the same thing.
Okay.
Now let's finally, we have an API endpoint.
We can consume this from our client application or front end.
So instead of consuming the JSON place holder one, we're consuming our own.
So that's easy.
Going back to Visual Studio Code, we are going to go to app.js under source.
And the line where we make the request to get all those post information is line nine inside the use effect.
So instead of calling that JSON place holder whatever slash post, we're going to call our own, which is in localhost colon 3001.
So save that.
Now in this case, the front end, we change some code to the front end.
If I go to the terminal for the front end here, I think when we make a change, it automatically watches.
That we change it so we don't have to restart the front end.
Okay, let's go to the browser and go to the front end app.
I have it in another tab, localhost colon 3000.
If I refresh with my network tab open, make sure the DevTools network tab is open so it can verify it's making a request to localhost 3001.
Refresh.
Uh-oh.
What happened here?
Oh, we have a problem with cross origin.
Okay.
If we click on the console, cross origin request blocked.
Same origin policy and this allows reading remote.
Okay, we're going to have to deal with this.
I won't talk much about course, but it's basically it's complaining because it expects you to request data from the same.
For example, localhost 3000, it would expect you to maybe fetch data from api.localhost or whatever.
So it's like thinking you're getting data from another place.
And by default, that's not allowed.
So what we have to do is go to the server side and we have to include a header that says, hey, we allow you to be cross origin.
That's okay.
Now to easily do that, we can install npm package called course.
C O R S.
Let's do that.
Going back here, you can carry a server.
I just for some reason open this terminal, but I can be the same one as the server.
npm, make sure in the root folder of the project npm install course.
So once we got that, we go to visual studio code.
Go to server slash index.
Now here, right after we define express call, we're going to do the fall app dot use.
That's the function.
Now I got to use, we're going to call course like this.
Now this course will come from require course.
So remember, we just installed course.
So we can require that library like this and putting a variable that will call course the same name as a module.
And then we can call this here.
Now this thing is called a middleware.
So in express, a middleware, something in between your request, your response.
So that means when a client makes a request, it first passes through the middleware.
And after passing through the middleware functions, it will finally reach the handler function for your endpoint.
In this case, the dysfunction for the slash post here.
So something is happening before this call of this function.
And it's the calling of the course middleware here.
So when we say app dot use, that means we're using a middleware for this express application.
So whenever I have a request, it will pass through the course middleware.
And then after that, it will reach my function here.
Now this car middleware will add some headers.
It will set some headers.
Remember, we use res dot set.
It's pretty much calling that.
So it will set some headers to allow us to do cross origin requests.
Now, because I changed that code, you know, I got to restart again.
Now you might be tired of doing that.
So let me teach you a trick so we don't have to do that anymore.
Now I'm going to call the server.
Now we would have to use what's called node mon.
But to do that, we got to install it.
So let's go here to my other terminal where I'm in the root of the project.
I'm going to say npm space install space dash dash save dash dev space no one mon.
Now I put dash dash save dev here because I want this to go under dev dependencies instead of dependencies.
And I'll tell you what it means in a moment.
Just install that like this.
Let's go back to Visual Studio Code.
I want to go to package dot Jason.
Now if you notice whenever you do npm install, it goes under dependencies, right?
But because I said dash dash save dash dev, it went under dev dependencies.
Instead.
Now why you have separate place?
Well, some people like strictly separating what software or packages are used just for development with those that are also used in a production environment.
So node mon is only for development where you just need it to watch the files and restart the server when we are developing.
We don't want to use that in production at all.
But that's why we separate and put them under dev dependencies.
Now you can see node one is there.
Okay, now to call node mon, proceed that npx and then node mon and then the file.
It's pretty much almost the same as nodeindex.js except you got to say node mon and then px before that.
Now why did I say npx before that?
Because this command node mon is under node modules slash dot bin and can see to scroll down.
There's a node mon command here.
Now if I didn't use npx, I would have to type explicitly.
In my case, I'm using Windows.
I got to use the slash backward like that.
But if you're in Unix or Mac, it's the forward slash dot slash node modules.
Slash dot bin slash node mon like that.
Okay, now I'm using PowerShell.
That's why it's messing up, but it's like that.
So I don't want to type this.
Let me use the other one here so you can command prompt dot slash node modules slash dot bin slash node mon space index.
In this case, it's server slash index dot js.
So it starts like that, okay?
So I don't want to type all this path, so I'd rather use npx.
So I hope you understood that.
Anyway, I'm going to kill this and trash this and go back to my PowerShell instance and just use npx before node mon.
Now, when I do that, node mon will be watching.
You can see here watching.
And if we go to index dot js in the server directory, if we do any change, let me say add some stuff here.
Save it.
You can see it automatically restarting due to changes.
So now we don't have to keep killing the server restarting every time you change the code.
Node mon is doing that for us.
Somebody asked the question, if you use npx, you shouldn't need to install node mon, correct?
No, so you need to install node mon.
So make sure you install node mon first.
The reason for using npx is so I don't have to type explicitly path to node mon dot slash node modules slash dot bin slash node mon.
Make sure to install node mon so that it's included in your DAB dependencies here.
Somebody said, I'm still getting runtime errors.
Where are you getting the errors?
Let's continue.
Make the errors will go away.
Let's see.
Yeah, we got there.
Getting there.
Okay, let's continue.
Save everything.
And we're going to go back to the browser here.
Let's see this.
Let's check the headers here.
Response.
Okay.
This should have been.
This should have added the.
Thing here.
Samarit's allowing resource.
Let me see.
Let's verify the code.
We use the middle where.
Chores.
HTTP.
Oh, yeah, you're right.
Let's see.
That's right.
Thank you for that.
It's using HTTPS, not HP.
Yeah, we don't have certificates for HTTPS, HP secure.
So make sure to change that to HTTP in the fetch.
Thank you for that.
There you go.
Let's go back here.
We got that sorted out.
And then.
We can observe in the network tab.
That it's calling for local host 2001.
We got a response there.
All right.
Everybody okay now.
Okay.
Now.
Let's go back here and see.
We're now using our back end and no longer using.
That typically code.
Now one thing for this app.
Is.
When we send a new message.
Clicking send here.
It goes to on send click.
But it's not actually sending the message to the back end.
It's just doing it locally in the browser.
So we want to be able to save that message.
How we would we go about doing that?
That's what we're going to do next.
So here when we click send.
We want to make a request to the back end and say hey.
There's a new message.
Here it is.
Now that's typically a post.
Request because you're posting something.
So the back end needs.
A post request now if you go back to index.js.
Now we can go here and say app dot.
Post.
And we can say slash post.
As well.
Because this will be post slash posts.
So we can have the same path but the different method.
This is a totally different pathway because the method was changed.
Now let's add the second function request.
The response.
Now if somebody comes in hey I want to add a new post.
So we got to figure out okay how do we read that information?
How are we storing the file?
So first we got to find a way to read that from the request.
So in the request there will be something called the body.
And then we're going to extract that information from there.
And once we got that.
First we need to read the file post dot json.
And then we got to insert the new message to the end of this array.
In an object.
Now we don't have all this actual information.
We're just going to use an object with the title okay.
And then once we insert that we got to overwrite the file post dot json with the new version.
Okay now to get the body.
If you're going to do rec the body dot whatever is passed in.
In this case we can say maybe the title like that.
Or even the whole body if you think it's safe.
But typically it's not good to read the whole body.
Because some people might add additional stuff trying to do malicious stuff.
So maybe you want to build your own new.
That's called new post here.
As an object whose title is coming from the rec body dot title.
So here I create an object.
And one property is title.
And its value comes from rec dot body dot title.
And I store that in the variable new post.
Now the reason I did this instead of directly using rec dot body is like I said somebody might try adding additional properties that have nothing to do with what your app is doing.
In hopes that it might somehow make your program take that and do some malicious stuff.
So be careful you want to filter out all the undesired properties and one way of doing that if you just hard code the object here and selective select only the properties that you care about.
Now in order to use back dot body.
We also need a middleware.
Because as it comes from the request.
We need to extract it somehow.
So we need a middleware that will come between the request and response and if it sees a body it will take that extract and place it in a JavaScript object.
So we have to read the JSON the string is just plain text.
For example, and it will convert to an object and it will make it available in request rec dot body.
Okay.
Now express already had that built in so we can just say here where we have all the use stuff remember uses to apply middleware we can say app dot use.
And then the middleware is express dot JSON and you call it as a function.
Like this.
So when we do that rec dot body will properly extract that body as a JSON object.
So we can use it like an object in JavaScript.
Now if you're curious about this you could add a console log here and log the new post and so on but the problem is we have no way of making a post request in the browser just by going to the address bar because remember that's just for get request.
Typically we have something like postman.
If you download the program postman that's a pretty good one to change the method to post.
And otherwise we'd have to type in the console of the browser fetch call with the method post and so on, which is actually the code right next.
But anyway you're going to see that right now.
So let's just keep this like this for a while and go back to the front end.
Now going back to the front end, where we send, we set the message that we call click send, it calls the function here on send click.
So what we want to do is make a request to the server to post a new message.
Now to make a request we can call the fetch function.
Now in this case is a little bit more involved because we're not only doing get we're doing post.
If you just have fetch with a string that's just a get request.
Now if I want to make it post I got to change a few things.
So first I'm going to say okay when a fetch from what's the address pretty much the same thing as the other one.
So we're going to paste that string.
Now come a second argument.
I want to say the method is going to be post.
Like that but I got to say okay what's the body?
What do you want to send?
Well we got to send whatever new message is right?
So in that case I want to send that in an object with a title being that new message.
Now this is an object so you want to convert that to a string.
So JSON dot string if I this whole thing.
Okay let me repeat that.
So we make a literal object here with the proper title.
And the value is going to be new message which is what the user types in the input that's next to send.
Now this object is a JavaScript object right?
We need to convert that to just plain text but in the JSON format.
So the JSON module has a function if you say dot string if I it pretty much converts this object to a string sequence of characters.
I can demonstrate that in the browser if you're curious about that.
Go to the console in the DevTools.
Let's say I have an object A with title hello world.
Let me make that bigger because it's too small.
Right? A is an object.
Now if I say JSON dot string if I A this is what we get.
It's pretty much a string in the JSON format.
You can see there's quotes around title and then the value colon the value.
That's all it does converting to plain text.
Now we do that because that's the way that works.
So we can send that in the body of the request.
Now when we call fetch like that it returns a promise.
Right? Because it takes time to go to the server, wait for the response, come back.
So it promises you it will give something if you wait.
Now the way promises work is if you want to fulfill this when the promises fulfill
that is when we got the data back we can handle that we say dot then.
So we can change this the result from the call to fetch with dot then
and press a callback function here.
And this callback will have the response object here.
Now we need to extract the body from that response
that and convert that to JSON.
So typically we always do we would usually do a response dot JSON called the function
and that will return a promise with the value when fulfilled
being the extracted body in JSON format.
Now because that's a promise that's returned here if you want to follow up with
I need to handle this promise we got to do another then and change it again.
Now this is going to be the post let's call it new or created post.
It could be any value for the function the function name here the variable name
could be anything you want I usually use descriptive names so I understand what they are.
Okay let me just also log that for you for now.
So we're going to see that in the console but we don't do anything with that just yet.
Save that and I'll show you how to debug the developer tools.
So you can see how to debug this anyway.
We made a fetch request to slash post method post and we include the body that is the new message.
Now going back here to the back end we're going to be able to see the rack dot body the title there
and then just for exercise for now I'm going to say rest dot send new post we haven't saved it yet.
So we're just sending back what we received right.
Now let's go back here to the browser and I want to teach you how to debug.
Let's see so in Chrome I think you got to click the sources tab in Chrome but different Firefox is debugger
and I can see the source code here after JS and I'm going to go to the place where I make this request.
Remember we just wrote this.
What I want to see is okay what's the value of created post.
I'm trying to debug to understand if it's coming correctly coming back to us.
So I'm going to place what's called a breakpoint in line 26 if I click the line number.
A breakpoint means the program will run and when it reaches this line it will stop for you.
So you can debug and see what's going on in the surrounding area.
Somebody adds well response to created post both contain the same response value.
If you're talking about the variable in line 23 response that's not the same as created post.
The variable in line 23 holds a response object that contains information about the response including the body.
Now all we care about is the body.
So we need to extract the body and convert that to JSON that is a JavaScript object.
That's why we call response.json function here and that value is a promise that fulfills with the extracted body
which is just a JavaScript object with the created post because that's what we built in the server side and send it back.
Okay once we got that breakpoint in there I'm going to refresh and I'm going to go down here and click send to trigger this function call
and you can see pause the breakpoint and you can see here line 26 it's waiting.
So we can hover the mouse over created post to see its value or you can see on the sides here the variables.
If you scroll down so on.
Now let me click control back tick.
Let me see if we can work that out here.
Chrome it usually works.
Let me go to console.
It's like created post.
So it seems like an object.
There's nothing.
You can see the post was made.
With the title hello here.
See this is what we send.
We send to the backend.
Now response is not returning anything.
Something is wrong.
Let's try to figure out what's going on.
Go back to Visual Studio Code.
Rec.body.
One way you can figure out what's going on here is you can console log like I said.
New post.
Like so.
But you got to watch out in the browser the server side terminal.
You got to watch out what's going on.
So maybe keep an eye on this server side terminal for that console log as we're going to go to the browser and try to do the same thing again.
Quick play to keep going.
And then we're going to go here and click send.
Oops, I didn't send with anything so let me refresh.
There's a hello there.
Click send.
Watch the terminal.
You can see here.
There's a problem, right?
New post is something title on the find.
So we got to figure that out.
Okay.
And I think I know what the problem is.
So when we send the data, we didn't say we're sending JSON.
I think that's what the problem is.
So going back to the front end.
Here, we make this request right with fetch.
But we're not telling the server, hey, we're sending JSON.
It's in JSON format.
So we got to go here in the code for the front end where we make the fetch.
We need to also include some header for the content type.
So we're going to go here and say headers and pass an object.
And let's put quotes because we have this dash content type colon application slash JSON.
Now, what this is doing, okay, in this request, we're sending the header for content type to application JSON so that the server will know, hey, we're sending JSON to you.
So make sure to when you are seeing the body of the request, you extract using the JSON malware.
Now save that.
And let's try again.
Watch the terminal as we go to the browser.
And click play, refresh, have the hello and click send.
Let's see the terminal again.
Now it says hello there.
See that.
So we had forgot to say to let the server know that we're sending JSON from the front end.
So it's important we have the header for content type set there as well.
And we can do so by setting the headers object in the fetch, the second argument of options, like so.
Okay, I know we're kind of going beyond time here.
So I appreciate your staying.
Let's just finish it off going back to index.js.
Now we got everything constructed correctly, not just got to save that file post.json, right?
So what we're going to do here is we're going to reference posts, right?
Remember, post is a variable that holds all the posts that were loaded.
Now we're going to take that we're going to push something to the end post isn't a variable that holds an array, an array has many elements to add an element to the end, we say push dot push, and a new post.
Now this is going to add to the post array here, but that post variable is is only memory.
It's not actually saved to the file.
So we have to save it to the file by overriding it.
So in order to do that, we have to leverage the FS or file system module.
Okay, to write the file.
So let's go up here and quickly do require FS under quotes and put that in a variable we call FS.
This is the file system module from Node.js.
It will allow us to write to a file.
So we're going to go here and say, okay, FS dot it has many functions.
Okay, one of them is write file sync.
And we can use this to write to a file.
Okay, it needs to know where's the file.
So we can say, okay, post dot JSON comma second argument.
Okay, what's the data you want to write?
Well, we want the post, but it has to be text, right?
Right now it's an array of objects in JavaScript.
So we have to use the JSON module.
Now we kind of do the remember what we did in the front end stringify.
Like so.
Now it needs to find what?
Well, the post.
Now if you do it this way, it will eliminate a white space and you probably will see everything without nicely formatted stuff.
So if you want to keep the formatting of indentation, you add some options here, comma, no comma two.
Now the second one doesn't matter.
So we say no.
But the third argument means how many spaces for the indentation do you want to apply?
I want to.
So this is just to pretty print the file.
If you don't have that, you're going to see everything in the same line.
It's going to be really ugly to see.
Okay, now let's add a third argument to the right file sync.
It's very important.
That's the encoding.
Now you want to make sure to always encode stuff in UTF-8.
So the encoding is going to be UTF-8.
Okay, so this will write to the file.
Let's try it out.
I'm going to go to the front end.
Let's just refresh this.
We don't need the breakpoint anymore because we debug this.
So you can click here, either right click here and remove all or you can click on the line again.
Okay, I don't care about that anymore.
Close that.
Now we know it's working.
Click send.
Now I want to watch the file in the Visual Studio Code post.json.
You can see now at the end, hello is there.
Okay.
So we add to the end and overwrote the file with the new title there.
New message.
Now if we go back to the front end and refresh.
Let's see here.
I was expecting one thing you got to watch out is.
Let's see.
If you kill the server, it might post push.
I was expected to see hello there.
So why didn't I see hello?
Let's think about it.
Oh, because only taking the first 10, right?
That's why I didn't see hello there when I refreshed.
So if you look at this, there's more than 10 and the front end is actually filtering
out all of the posts only takes the very first 10 ones.
If you want to change that, remove the slice 010 from line 14 in app.js.
So it doesn't filter out the posts and we can try seeing the front end again and refreshing.
Even though it's a mass in CSS, the style, you can see at the end, there's a hello,
which is actually what we had just added initially.
One challenge for you is fix this so that there's a scroll bar here in this container.
So you can scroll down if there's too many messages, but that's for another time.
Okay, if you want to prevent that, you can do the slice again there.
You can even take the maybe the last 10, I think you can do negative 10, I wonder.
Let's see if that works.
Yeah, that works.
Anyway.
Yeah, one thing to notice here is I assumed that the message that we sent to the server
side was properly inserted, but that could be errors.
Maybe the back end can reject your message.
So that's why we don't always want to set this message here, but only when it's successful.
So you want to move this setting of the message here up to the dot then of the created post here,
and you can remove this console log.
And if you ever get any errors, I'll leave it as a challenge for you.
You can put a dot catch here with a callback of the error function like this,
and you have to handle the error here.
Maybe you can create a state variable that will hold an error message and you can set that like set error to fail to post message,
something like that.
And then you can go scroll down here and put a, I don't know, you can go here to the send or even outside and add a div with the error.
If there is an error, something like that.
This is just a draft.
So you got to use state up there and so on, but just some hints if you want to handle the error there.
Now to simulate an error, you can always go here and throw new error failed.
And this will simulate having an error.
So every time there's an error anywhere in this promise chain, it will jump to the catch block and execute whatever.
So if I put a thrown new error here with whatever message, that's how I simulate the error, okay?
Error simulation to test dot catch below.
So that's an exercise I leave for you if you're interested in building upon that.
All right, so that's it for today.
No comments yet (loading...)
No comments yet (loading...)
Did you like the lesson? ๐๐
Consider a donation to support our work: