Video Transcript
So let's continue building the app and talk more about React,
the library we use on the front end to build user interfaces.
The repository is this one I'll be using for the source code,
and let's get started.
So I already have it open here,
and let me open Visual Studio Code.
By the way, if you recall,
all we did was CD to the Web Client Directory and type npm start.
And we did all of that after running Create React app to generate the project.
So you should have something like this after doing npm start.
If you're downloading the repository for the first time,
you have to npm install first before doing this to get all the dependencies.
npm space install.
Anyway, we are going to localhost colon 3000 in the browser.
And let me put on Firefox, sorry, on Chrome.
It looks like this so far, and I'm zoomed in so you can see better.
Okay, let's go to VS Code,
Web Client, Source.
If you recall, we have a generator project for the React application under Web Client.
Previously, we had written HTML and CSS and JavaScript files
in the SRC directory at the top level,
but then we have now moved on to React application.
So if you wanted some exercise, you could convert all of these HTML pages
to React, just follow the pattern we did before.
Anyway, we're going to go Web Client Source app.js,
and we have this messages component here so far that will be used from the app component.
So if you recall, basically, in the world of React, we create what I call components.
You can think of them as like our own HTML elements,
and the way we create them is using a function definition.
So we declared this function called app here that returns some template that looks like HTML,
but it's actually something called the JSX,
which is some syntax to show here to call us to react.createElement function.
And then we instantiated or kind of show our messages custom element or component here
that we created outside.
And we just have a function definition.
We did all this previously, and then finally we return that template that we see in the browser,
which is basically this, have an h1 there, some text area button
to submit the form that underlines that.
And then we got a bunch of deals with all the messages.
Now, first thing I want to show you is how to better organize your source code.
And you don't have to have everything in one single file.
You can actually separate your components into separate files,
and that's what people usually do.
So if you want to create under SRC a folder, let's call it components.
You could move messages there.
Let's say I create messages.js here.
By the way, you might also see the extension.jsx whenever you have JSX in the source code.
If you are using TypeScript, you will see .ts or .tsx.
And usually we use JSX and TSX when we have some JavaScript with the JSX,
basically the template that we've shown for the components.
But for my case here, it's very simple.
I don't have to do that fancy stuff.
Anyway, I'm going to have the app open down here in this panel to the bottom.
And all I have to do is take the definition for messages, the function,
and I start from before the word function.
I'm going to hold Shift and press all the way until the end of curly grades
to sort of highlight it all.
And then I'm Ctrl C. If you're using Mac, it's Command X, right?
Sorry, I said Ctrl X, not Command C.
Let's go here, Ctrl V, or Command V on Mac to paste.
And then in order for us to be able to use messages, this function, from another file,
we have to, in the file that we need to use it, import, in this case app.js,
you're going to import messages from dot slash component slash messages.
Let me disable my thing because I always forget.
One moment.
Reload.
There you go.
All right, so we first got to import some word.
Normally, you've got to give the path to the file.
In this case, it's dot slash, which means current directory slash components slash messages.
And it's implicit to be dot.js.
You can omit the extension, but it's pointing to this file here relatively from where app stands.
And then from the messages dot.js here, you have to export the function to make it available
to those who want to use it from another place or another file.
So you can either do here with export default before the function, or you can do afterward
if you like to separate with the same export default messages, either way, it works.
And now we got to fix some issues because it's complaining here, it's probably going
to work, but it usually complains if you use something it doesn't know, you got to import
at the top, import react from react, like that.
And then we go through the code to see if there's nothing else that we need to import.
And looks like no, I didn't get any visual studio code hints.
And then back to app.js, you can just save that as it is.
By the way, we did this messages CSS, we probably want to move this importing of the style to
be specifically for messages instead of app.
So I'm going to move that as well.
And that's how you move you isolate the logic to other files.
Typically people like to isolate every component one component per file.
That seems to be the norm these days.
And we like to better organize with a folder like components, for example, I might also
see people organizing by pages, especially people who use an XJS or frameworks on the
server side for react.
That's common as well.
Usually they have the file based routing, which is a traditional next to us.
But now they have another one, the app router, but in any case, that's the refactoring or
changing of the code to improve organization that I wanted to do first.
The next thing I want to touch upon is how can we actually retrieve the data from a server?
Because if you notice, let me close app and focus on messages.js here.
If you notice, we have a hard coded list or array of objects that each represent a message
or a comment that we want to show, but actually this data is usually in practice comes from
a server, a backend server, and that server in turn has the data stored in a database,
which we will learn in the later sessions.
But for now, we got to figure it out using a fake one, a fake backend.
Okay, let me just check Google Chrome to see if there's no errors here.
So we got problems with the refactoring and changing the code.
So that's why it's always important whenever you change your source code, you want to test
it to see if it's still working.
So you want to go to the browser and see if there are no problems, test the app, try to
write a message and so on.
So clearly there's a problem here because if you go back to the code, I moved the import
for the CSS, but now when I say .slash, it means somewhere within components, but there's
no messages.css within the components directory.
So there are two ways to go about this, either you fix the path to .dot, which means one
level up in the directory chain, or I move messages.css to actually be within components.
I'm going to do that, going to pick drag and drop messages.css to the directory components.
So they're in the same place, therefore the .slash relative path current directory will work.
Okay, let me just take some time here to post a link to people who have just come in.
So we are doing the app that's from this repository, I paste a link to the Zoom chat.
So if you want to follow along and don't yet have the source code, you go to this repository
and clone it or download the zip either way.
And then you're going to go CD to web client, we're going to MPM install, and then you're
going to MPM start.
I paste the commands to the Zoom chat.
Okay, going back to what we had to do.
So I want to take this, first let's think about if you were to get the data from a server,
how would you actually set it in a React application?
Because if you think about it, when the user access your web page, they're not going to
see the post yet, because it needs to first get that data from a server.
So you're going to wait a little bit between not seeing anything and seeing the post.
I don't know if you ever noticed that in websites today, there's often some jumps sometimes,
like you first access the website and it's loading stuff, and then out of the sudden
it jumps and then the data comes along.
So we're going to use an effect here.
Let's first make this, let me take this.
I'm going to cut this array here, and I'm going to keep it in my clipboard, and I'm going
to put it empty.
So at first we're not going to see anything like this.
And then we are going to do something when this page is loaded.
So to do that, I'm going to use an effect from React.
So we're going to use react.useEffect here.
So we're going to do this within the function for the component in the top level here for
the body of the function.
But make sure you don't write it inside any of these inner functions, okay, as to be outside.
So useEffect is a hook that is going to be calling some function or instructions repeatedly
after every render.
So in React, when something changes in the state, it renders the component over again.
So it's going to trigger this function call given to useEffect.
But you can also kind of calibrate that, say you only want to call this function when
some other value changes.
You can do that using an array of dependencies.
But for now, we're just going to keep it simple.
We're going to do it like this, when the component mounts, that is the first time you access
the page, we're going to request the server for the data, and then set the array of messages.
And then after that, that was the first render, and we're not going to do it anymore just once.
So in order to do the useEffect only once, we have to pass an empty array of dependencies.
Okay, so the arguments useEffects a function with a set of instructions that you want to
do once this renders.
And then the second argument will be an array of dependencies.
But if you leave that empty, it will mean that I only want this function to be executed
once after the first rendering of this component.
And here I'm going to do the actual setting of messages to those messages.
I don't have a back end yet, but I'm just simulating it.
And to do that, just for the sake of example, let me put a timeout here.
So timeout is basically a function that will call another function that you pass after a
certain number of milliseconds.
So I'm going to pass a function here.
And after let me put three seconds, which is 3000 milliseconds, I'm going to put this
inside just to simulate the back end.
So what's happening?
Okay, set timeout to your passive function.
And this function has some instructions that will be executed after three seconds.
And then after three seconds, the function here inside will be called and will set the
messages to this array of three objects.
And because we set messages, we change the react state.
The react state having changed will trigger another render of the component.
And then once it hits the mapping of the messages, instead of mapping the empty ones, an empty
list will now map all the three ones.
So let me try in the browser.
I'm going to refresh and wait three seconds, one, two, three.
And you see it appeared after three seconds.
Okay.
So that's the hook.
Use effect.
So if you want anything to happen once the component renders for the first time, you
can pass a function to use effect and a second argument to use effect has to be an empty.
Some people might use effect like this, writing it without react dot.
And if you want to do that, you got to go to the import and put a comma here, use effect
to the kind of like import a named export there.
Works the same way.
Okay.
And you can do this, that same thing for use state, you might see that as well.
So you write use state here, comma, use effect, and you don't have to type react dot.
Okay.
Great.
But so far, I haven't talked about backend server, but I have to talk about promises
first.
So let's go to the browser.
In the dev tools console.
By the way, there's an error here in valid on proper class.
Did you mean class name?
Let's fix that.
Where is it?
A div.
I think I type class equals instead of class name somewhere.
Let me look for class equals.
So line 40 gate messages.js.
I should type class name because I'm using react.
And let me make sure I don't have any others in app.js.
Yeah.
We're good.
Okay.
If I go back to the browser and refresh, yeah, I don't see it anymore.
It's a common thing that we have to do as we switch from playing HTML to react.
Okay.
So let's talk about promises, because the nature of getting or retrieving data from
a backend server is asynchronous, meaning it might take some time to get a reply.
So we're going to ask server, could you please give me all the list of messages to display
in this message board?
And that process take time.
Okay.
I got to connect to the server and the server is going to do some work to look to ask the
database.
And eventually you're going to get back a response.
Now how do we handle that weight?
You know, I got to wait.
So it's either going to be accepted or not.
That's why I have promises in JavaScript.
Okay.
So a promise, you can create one if you say a new promise like this.
Okay.
And then it passes a function like this.
And basically a promise, if you expand this, we'll have a state that initially is going
to be pending, meaning we're waiting, waiting way, and eventually it's going to fulfill
with some value, or it's going to be rejected with an error.
So what, why promise promise basically, okay, when you create a promise, you're, you're
going to get something back, but as promised, but if you wait for it, so let's say I create
a new promise here, and I'm going to give something back, maybe I'm going to do the
same technique of set time out here, and I'm up to three seconds, I'm going to resolve
with some value, hello.
So when I do that, the promise will be pending, pending for three seconds, finally after three
seconds, we're going to resolve with some value there.
And if you expand that, you're going to see the state is now fulfilled, which means, okay,
we better, the resolve function was called with a value hello, you can see the result
here.
All right.
So why is this important?
Because we're going to make a request to the server, and we're going to get back a promise.
So we have to learn how to handle the promise after the promise is finished, how do we execute
the instructions, but only after receive response.
So let me copy this code again, putting a very called P.
Okay, so P is a promise, a variable.
And the first time I use it as it's pending, the second time is fulfilled with a value
hello.
So the promise that we're going to get from that request to the server will eventually
be fulfilled.
But how do we handle doing something after it's only it's been fulfilled, we have to
do P dot then, like this, and then you pass a function.
And this function will receive as an argument or parameter here, the value that was resolved,
in this case, the hello message, we can say message here.
And then you can do whatever with it.
Maybe you want to console log that.
We got the following from the promise.
And then comma message.
So basically I'm saying after the promise, the variable P holds a promise.
After the promise has been fulfilled, then I want to call the function that I pass.
And since it was fulfilled of a value,
that value is accessible through the message variable here.
So you can do whatever.
So it's going to console log.
We got the following from the promise we got hello here.
Console log is just a function to print a message to the console here.
Now, if the promise fails, you can reject, it gets rejected.
So let me simulate a failing.
Failure, if I go press up by keyboard, I'm going to redefine that promise.
And I don't want to do the resolve, I want to reject the promise.
Now you reject usually with a narrow object.
So you can say new error and some message for the error.
Something went wrong.
Something like that, okay?
So a promise is rejected with a narrow object.
And I'm simulator that.
And you can see right away that it's been rejected because I didn't put a time out.
So I probably should do that.
So let me put a time out for you to simulate that delay,
receiving the message from the server.
So I put a time out there.
And then three seconds, which is 3000 milliseconds.
So initially it's spending, and then next time I see it, it's been rejected.
You see that state rejected with the promise result being the error object.
So how do I handle the error?
You can say dot catch, for example, p dot catch, that's one way.
And with the same way to catch your passive function,
in this case, it's going to receive the error as the argument.
So you can do whatever with the error in life, for example.
Unfortunately, the promise failed with the error, and then you can log the error dot message.
Because an error object has a message property, so you can do that.
And it's going to say that, okay, because this promise, the p is a promise,
it was rejected.
Once the promise is rejected, it goes to the catch block and
calls the function pass to catch.
And this function console logs your, my message with the error dot message.
Okay, so that's promises.
Now, in these days, you might also see a sync await.
That's also not a way of kind of handling promises in JavaScript.
But yeah, let's keep going now and actually do the server side.
So here in messages.js, under the use effect function,
I want to call the server to get the data.
Now this server, I will use this website here,
called jsonplaceholder.typycode, or typicode.com.
And it's basically a fake backend server that we can use to pass things.
And it has a bunch of resources.
And one of them is slash posts.
And if I click that, I see like a hundred, I think.
Let me pretty print this.
Oh, it's a red print print.
Basically, it gives you back a JSON response with an array of objects.
And each represents like a fake post of many properties.
Let me zoom in for you.
For example, this first one has the property user ID,
which is basically the idea of the user posted this.
I have an ID as identifier for the post,
a title, which is the title of the post and then the body here.
OK, so it repeats with the kind of same fake data and goes on and on.
I think you can limit if you go here and say question mark underscore limit,
like three, it can get just three.
So I'm going to use this endpoint.
So I didn't talk much about how the apps these days retrieve data.
So basically, we have the front end and then the back end.
The front end is what people usually see, right?
The website or the mobile application or the desktop application.
And then that part, when it needs to show you some data,
it will ask some back end server.
And the way they communicate is through usually HTTP protocol,
hypertext transfer protocol, and then the exchange messages.
And then in the body of that response that you receive,
you can pass in some text.
Now, that text can be formatted in a certain way.
And the way people usually format it in the JSON, J-S-O-N,
which stands for JavaScript object notation,
which is this format we see here,
which is basically a JavaScript object format.
We have like objects and we have properties with quotation marks and then values.
And the values could be like the JavaScript types like number,
can be strings, which has quotes.
It can be true or false values.
And it can even be another object in itself.
Okay, so this is like the preferred way people,
the apps interchange communicate today.
In the past, and still some legacy ones still do it,
they use XML to do this.
But JSON is much simpler so that's the one that's popular today.
In any case, so let's copy this.
So how do you make a request to get data from a server?
I also have to explain that.
If you go to the browser and type this,
press Enter, that by default is an HP get request.
Now, how do you do that with JavaScript?
Let me open the DevTools again.
So there's this function called fetch that we can call to retrieve something.
And you have to pass the URL of the resource or endpoint.
In this case, it's the one here in the browser.
So you can paste that under quotes and you press Enter.
And you see it returns back a promise.
If I expand that, it's now fulfilled with a response object.
And if I click that response, it has a bunch of properties.
Now, this response object by itself, it has a body here, you can see.
And if you click that, it's a readable stream.
So it has to be kind of like parsed or extracted.
And to do that, we have to handle the promise.
Remember to handle it, we have to use dot then to do something after
the promise been fulfilled.
And we're going to take the response and
we're going to extract from the body the information.
So if I do this, which returns a promise, I can do dot then and
then pass a function.
And this function received the response.
Now, this response is what we saw here.
We need to find a way to extract from the body.
And to do that, there are several ways.
And one of the easiest ways is to do response dot JSON function like this.
And then you return.
Now, this JSON here, function of the response object,
it will read the response and extract it and
parse it in the JSON format.
That way, you're going to either get an array of our object
in a promise that's fulfilled.
So if you do that, you'll get yet another promise.
And if you expand, it's been fulfilled with a result being an array of three things.
And if you expand, here's the objects that correspond to what we saw in that response.
So that's the first post, the second, and the third.
Okay, so that's why you're going to see in the code.
Because it's a promise, the JSON function returns a promise again.
You have to handle that.
And the way we do that is with a chain of promises.
So you can actually do another dot then outside.
Which is basically mean, okay, this one returns a function.
Therefore, when I say dot then, it's going to handle the function.
And then this one returns a promise.
So we're going to handle that too with a dot then outside.
So repeat the same pattern, function with an argument.
Now that argument is going to name its post or something because that's what it represents.
Now the name inside the function arguments is arbitrary.
But usually I choose something descriptive of what that really means,
what the promise fulfills with.
And then you can do whatever the post here.
Maybe you can just let me console log the first post dot title, right?
It's an array.
So post brackets of zero index zero means first element.
And then it's an object and I can do dot title to get the title.
And you can see that it's been console log the title of the first post.
Okay, I took the time to explain our promises here so
that we can finally jump into the code and understand, makes more sense.
Because in the past it would just jump in the code and write a promise right away.
The fetch call right away and people would kind of be confused.
So I hope this helps a little bit.
It might not make sense even if I expose it to it, but
at least you got some exposure and eventually things just come into place.
Okay, so we got the messages component.
It's been rendered.
The first time it's rendered, it's going to call the function provided to use
effect with the, that has the dependency array empty.
So we're going to go here call fetch because I want to retrieve data from
a backend server.
We're going to make an HTTP request and by default fetch uses the GAT method.
Okay, that's why I didn't say anything about GAT posts.
And provide that link, by the way, I paste this in chat.
Okay, and then this returns a promise.
Therefore I must handle the promise, the value that was fulfilled with a dot
then and pass a function.
And this is a response always some common mistake people make when they use
the fetch function is they don't realize that first returns a response object.
So you got to be careful.
And then from that response object, we've got to extract the body as JSON.
So we're going to return from the function a response dot JSON like this.
Now something I didn't mention is, okay, what if something bad happens?
What if the server doesn't give me back a good response?
It rejects the promise.
So you would, first you got to put a catch outside.
And then you put a function with the error.
And then do whatever to do error handling.
Maybe you want to display an error message to the screen or something like that.
Now this, in this case, for the first fetch.
A problem that could occur is maybe you're trying to get to the server.
But you're offline, you don't have a network connection.
That's one case where this first fetch here would throw an error.
And then it would hit the catch block here.
That's the first.
Then if this actually succeeds, the next problem would occur is,
what if I try to get a JSON from a response that doesn't actually has JSON?
So that could also be the problem.
So usually people before doing that,
check if response is actually okay.
So this is error handling.
Because there could be the case that maybe you're trying to,
the server understands your ask a request, the server connected,
but they don't know maybe this endpoint or this URL
doesn't actually point to any resource.
So it could give back 404 status not found.
In that case, what do you do here?
Like you have to check if the response is not okay, right?
If it's okay, this means the status code
was within the 2XX range, like 200k, 211, created that kind of stuff.
All right, and then let's assume happyPath for now,
meaning everything is fine, we're not going to get any errors.
And then you actually have to handle this promise that's returned from this.
So you have to add another den here outside with a function
that will actually get the posts.
So you see there's this chain of .den and then .catch.
So be careful where you put them, you've got to be outside this .dan here.
Like if you were to ignore everything there, it has to be outside.
Anyway, so once you finally get the posts,
you can set the messages like we did here.
So you can take this part here, move it inside the .dan here,
and let me remove the timeout.
And then this is no longer hard coded, right?
This would have to be posts, but there's a catch.
My messages, objects, expect some message property here.
However, I don't think they use message, right?
They use title or body, if you recall.
Their objects has title and body.
So we either have to change our code or we could just parse that
and follow our own by mapping to new objects.
So whichever, if you were to change our code here,
if you just leave it as it is, we would go down here
and where we do the message.message,
you have to change that to a title or body, right?
I'm using title for now.
So if you have .message somewhere, it has to be .title.
Now, if you didn't want to do this, you would leave it as message.
If you have to go here, map your responses,
you would do post.map, and then you're going to take the post
and you're going to return a new object
that pretty much copies from post
and introduces the message property.
That's basically post.title.
That's the other way.
Okay, I'm going to copy this.
I prefer the short way for now,
which makes more sense to me.
So I'm going to revert, but I paste the code to the Zoom chat.
Okay.
It makes more sense, right?
Title, a body, so on.
Let me see what I had before.
Just set messages for posts.
And here, in the mapping, I do .title.
Okay, let's check it out.
Now, it's working.
If I refresh again, yeah.
Yeah, it's so fast that you barely notice,
but I notice initially it's blank.
And then, momentarily, it fetches all that stuff.
The promise is fulfilled.
And then it goes to response.json to extract,
and then the other promise is fulfilled.
And then finally, you got the post.
You call set messages with the array of posts.
And because you change the state,
react, re-renders the component,
and the DOM here, the document object model,
is updated to react, doing its lifting for us behind the scenes.
Okay.
So usually when we have data retrieval,
like I said, there's the loading state and the error.
So let's try to simulate some error.
So let's go here, let's say I'm offline, something happens.
Let's show you how to do that.
So in Google Chrome, for example,
Firefox is kind of the same.
Press the DevTools network, and I can click here.
No throttling.
I can actually do offline,
which will make me act as though I'm offline.
I don't have a network connection.
So if I do that and refresh,
I can actually do offline.
And I can actually do offline.
So if I do that and refresh, no internet,
you see that doesn't reach the server.
So, but let me try to simulate,
I have the app running,
and then I somehow cut my connection.
So to do that, I put no throttling.
I have to go to sources, I put a breakpoint.
Let me do, what is it?
Message is yes, right?
Let me first refresh here.
Oops, refresh.
And then sources, message yes.
I'm gonna do a breakpoint here in the user fact,
right at the line for fetch.
So when I'm about to fetch,
I'm gonna make myself offline.
So let's try.
If I refresh, I'm not fetched yet,
but I'm gonna go to network, click offline for throttling.
And then I'm gonna back to sources,
and I'm gonna let it through to the next,
I'm gonna let it play, let's see.
What happened there?
See another?
Yeah.
So we see in the console,
we got an error, internet disconnected.
But from a point of view,
like of the user using the app,
they have no idea what happened.
You just see blank where the message is supposed to be.
So we need to improve this
with some error message there, at least, right?
Let's do that.
So we're gonna go here,
maybe before the list,
I'm gonna add like an error here, message in a do.
Now I need to store that somewhere.
So I'm gonna make a variable in the state for that.
Let's call it posts error, how about that?
So I only wanna show this if this variable
has something defined.
So I can use this technique of short circuiting like this.
Basically, this is this and that.
So if the left hand side is defined,
in this case, it's gonna be a string
or a sequence of characters.
If that has at least one character,
the right hand side will be checked
and will show the do.
If this is something like not defined or an empty array,
empty string, sorry,
it will not go and do the right hand side
of instead short circuit
and just return the value for post error
as either empty or not defined.
Not defined, in which case react takes that as something
that you don't wanna show anything at all.
Let's define it here up into where we do our state stuff.
I'm gonna do a use state.
And I can either do no or defined or empty string.
It doesn't really matter because in JavaScript,
an empty string is considered a falsely value.
But if you wanna be really like a string,
you can put no there to be more clear.
If you wanna use it like this,
like how it's telling you about,
you can do use state here like that.
That way you don't have to type react dot.
And because this is a use state call to the hook,
it returns an array of two elements.
So we do structure to extract the first element
and the second.
Let's extract the first element, oops, equal sign here,
into post error.
And then the second element will be set post error.
That's the mutating,
mutate function to change the value of post error.
Okay, so here we use a fact.
If we fetch and we fail the fetch
because we're not connected to the internet,
it will jump to the catch
and execute these instructions here.
So in the catch,
you can set the post error to the error dot message.
That way when you do this,
you update the state for post error,
react will re-render this component.
And ultimately, because post error here
will be like some sort of error,
like internet is connected or something.
This is defined, like has at least one character.
It's true the value of JavaScript,
therefore it's considered true.
So the right-hand side of the and logic will be return.
Okay, if you wanna look this up,
it's logic and logical and
okay, you can look at the truth table for that.
So for and most,
most of has to be true to return a true value.
Anyway, let's try again.
So how do I do that again?
We gotta do, go back to no throttling.
And I'm gonna put the break point, refresh.
We're paused at the break point.
I'm gonna make myself offline.
I'm gonna go to services, play, play.
And I see the error message there.
At least that we got now.
The user wrote now, oh, okay, failed to fetch.
Something is wrong.
Okay, now let's do the loading state.
Let me remove the break point here
and make myself online again.
Mind you, I didn't, there could be more errors, right?
Maybe the server returned 404.
So for that, we do have to check here in this one.
Maybe you could try something like, if not okay,
you can do throw new error with the response.
I think you can access the status stacks or something.
Can't recall.
You have to use the depth tools.
But anyway, I'll put dot, dot, dot something here.
And because if you do this throw here,
throw will basically raise an error
and will jump right to the catch block.
Therefore, it will set the post error.
So that's one way.
But let's look, let's handle the loading state.
So how do people show that spinner
or at least a loading message?
So let's use state here to create a loading state
that's initially true.
Equal sign, const, post loading,
let's call it that, set post loading.
So basically I want to keep track of a Boolean value
that's either true or false,
that we represent whether the posts are loading.
So initially they're loading,
so I put initial value true there.
So we got the user fact here.
So we got the fetch.
And once the, we set the message posts,
that means we have finished loading.
So after that, we can call to set post loading
to false, right, to no longer loading.
But also you have to keep in mind,
what if there's an error?
That also means I'm no longer loading.
So you have to do the same thing after set post error.
So there's that.
And usually if you have a mechanism
that you can always retrieve data multiple times
throughout the lifetime of the app running,
you could actually make here in the beginning
set post loading to true to initially,
okay, if I submit a form for example,
I set loading to true, do all my stuff,
and at the end I set to false.
But in this case, I don't need it
because it's just executing once.
Okay, now we got to show that message
or a spinner if you have an icon.
Maybe we can try something like,
here next to the error we can add
either before or after, it doesn't matter.
If your post loading can follow the same technique,
short circuit, if that is true,
then the right hand side will be returned.
Otherwise it doesn't do anything.
We can show like loading div or a spinner or whatever,
maybe you can leverage font awesome
and put a spinner there or create your own animation CSS
or image or whatever, just keep it simple.
Now this is going to be hard to detect.
So we have to put a time out there to simulate the delay,
exaggerate, but let's see, I see loading momentarily.
Let me try to throttle my connection.
If I make my connection like slow or 3G,
it's like slow, let's see what we got.
It's really slow, kinda slow, loading, loading, loading.
Okay, that one's a little better.
But if you wanna really see loading all the time,
just put a time out in your user fact function body,
and it should simulate a very long delay.
All right, I think everybody saw the loading there.
So it's gone once we set the loading back to false.
Okay, let's try something to finish off
of simulate a fake submission,
cause right now we do hello and just not calling the backend.
So if you recall, we have the text area and it's under a form.
So when I click write message,
it calls the function from the unsubmit handler,
which is add message.
And typically what we do here is,
we wanna first call the backend server.
So we make a fetch to that very same fake one, oops,
except you have to do a post request.
So you do a fetch to the same kind of address
without the question mark.
But it has to be a post, not yet.
So how do you change that?
Well, the second argument to fetch
can be an object of options.
And one of the options of the method,
you can put post like this as string.
Remember object property column value,
the value of the string, so it has quotes
and a comma to separate with other property value pairs.
And also wanna change some things
because I need to provide, okay,
you're sending us a new post, right?
So give us the title, the body, and so on and so on.
So that's the body property.
Now the body here, you have to take what?
Remember we have new message, right?
So we have an object.
So we can take this one and put it here,
but it doesn't call, it's not called message,
it's title or body or whatever, right?
Body
and other, possibly others, right?
So I'm gonna comment these.
By the way, a comment in JavaScript,
basically it's ignores, the computer ignores
everything after the slash slash.
So this is actually, you can imagine the computer
doesn't even look at that, these two,
and we would just see that.
Okay, so I'm passing the body,
but I have to do something,
it's called make this JavaScript object a string,
we're in plain text.
To do that, we call it jjson here,
dot string if I and pass that object.
So this will take this object convert to a string.
Let me show you in the DevTools,
if you're confused about that.
So we have an object, right?
Title, hello world.
This is an object, right?
Type of object is object.
Now, I wanna need to convert that to text,
plain text to send in my request.
So I can do json string if I OBJ,
and I get a string,
which is basically sequence of characters,
just like this, in JSON format.
So that's what it's doing, right?
Type of this, type of that, string.
All right, so we gotta do that here.
Don't forget.
Okay, now we gotta also let the server know,
hey, we're sending in some data,
and the format is json, it's plain text,
but it could be plain text or json, right?
It's text, but it could be plain or json.
So we need to pass some HTTP headers
to let the server know.
So we can pass headers through the headers property.
And that header is called content-type,
but because it has a dash,
we gotta do some quotes here,
surrounding the name of the property.
And then you can say for the valid application, slash json.
This is a standard naming name for that.
It has to be that way.
Okay, let's see.
And that will make the posts.
And that whole thing returns a promise.
So what do we do to handle a fulfilled promise?
We got a dot then, yes.
And that returns a promise, right?
That fulfills with a response object.
We gotta do that same thing over and over again.
If response, let's just make it simple, I guess.
Not okay.
The status code is not within 200,
I'm not throwing you anywhere.
Fail to submit posts.
And I think we can maybe investigate that in DevTools.
And then if not, we keep going.
If this is not the case, the response is okay, it keeps going.
This is the next statement, by the way,
let me refresh your memory.
So if statement is if the condition within parentheses is true,
execute what's between the curly grids.
So response is an object that has a property okay,
that we true or false.
If the response went well, it would be true.
So when you have true here and you put the bang before that,
it flips that to false.
So it flips to false.
And if it's false, it doesn't execute the body, okay?
And after that just keeps going like that.
If it were true, right, response, we're not okay, that's false.
False gets converted to true.
Therefore it executes this throw.
Because you throw, it just skips everything afterwards
and go to the catch block,
which we gotta put here outside.
And you're gonna handle the error, right?
Handle the error, maybe set a state message.
For now, just put console error to do.
And finally a response JSON here, same thing.
And then if you want to extract anything from the response, right?
If you care, maybe usually you receive the object back
with an ID so that it can set the ID.
So that's something you could do.
So that then function createdPost, let's call it that.
And we can update the messages.
We're gonna copy all the messages,
but we're gonna add at the top the createdPost like this.
Like this.
That way it's gonna include the ID.
And by the way, this has to be not response.
Okay, I'll revert that back.
Okay, let's see if no problems.
I'll debug with DevTools to let you know what's going on.
Okay, we're here.
We'll go to sources.
Oops, let me put it back to network to now throttling.
Otherwise it's too slow.
Sources, I wanna go here and message JS.
I wanna add message, I wanna put a breakpoint here
and here.
Okay, I put a breakpoint right after we fulfill
the first promise and then right after we fulfill the second.
Now let's try hello, write message.
So if you click network, it's gonna see here,
we've made a post request.
You gotta click XHR patch if you wanna narrow down.
It's the third one with the post.
See the post was here.
Here's the payload, this is the title hello.
If you click sources, just a string.
And headers, if you scroll down here, my request,
headers includes content type application JSON,
which is what we set under the headers object.
Okay, and then going back to sources,
if you wanna look at this response,
the status was 201, which is basically created
and there's no text and yeah, it's okay.
If you hover over okay, it's true.
Okay, this is basically checking if the status is within
the 200 range, cause 200 usually means everything went well.
And if it's outside 200, like 300 something, 400 something,
something wrong happened usually.
And we can just go and to the next line
and you see it skips the throw, it doesn't do that.
And then you can click play to go to the next one.
And you can see here, it gives you back the post
that was created with the ID,
which is usually what happens when you have an actual server.
And once you create the post with the title hello,
it gives you back the identifier for that post
in the database.
And we're gonna set messages here.
Let's see what we got.
I got hello at the top.
So it's there, so you can try again.
And it's going always to the top,
always preserving the previous, putting it at the top.
Okay, now let's go back here.
Let me just finish off simulating something bad happening.
Maybe you failed to submit the post.
You can follow the same pattern.
So you create a new variable here.
You can call it, for example, submission error,
set submission error.
And you state initially could be no, no error.
And then in the view here for the return,
maybe under the text area here, after the button,
you can put it, if there's a submission error
and short circuit with a div with the error,
fail to submit post.
Here's the error message, submission error.
And close the div.
But if you recall, the curly braces needed
when you need to actually interpolate,
sorry, substitute the value of this variable.
If you don't have the curly brace,
it will literally show the word submission error
and not the value that it points to as a variable.
And then to set that error,
you can go here to the add message,
write fetch, then catch,
and you would do the set submission error
with the error dot message there.
Okay, I can simulate that for you
by doing a throw here in the second fulfillment.
I can simulate by saying like throw,
you ever couldn't create the post for some reason.
Actually here or there, it doesn't matter.
Let's put it here about that.
Let me run this.
So if you try to submit, it would just fail here.
The other thing is appearing, by the way,
because I didn't fix this part here.
We have to remove that.
So let me remove this here.
And we have to clear that only when it's successful, right?
So we move that to after we create here.
That way it fixes that problem that we had.
So if you go back, let me refresh.
I write message, fail to submit.
So that's what you see.
Obviously you make it better,
make it like a red banner or something.
Make it fancier.
Anyway, I'm gonna remove that
because we don't want that.
It was just a simulation of the errors.
Line 51 removed.
So if this one were to happen, it would actually do that.
And I didn't put the message here.
If the backend included some response,
you have to put here after the quote, colon.
But anyway, that's it from that.
And I think this lecture, we're gonna call it a day.