MERN Stack Tutorial for Beginners - Deployment Included

Estimated read time: 1:20

    Learn to use AI like a Pro

    Get the latest AI workflows to boost your productivity and business performance, delivered weekly by expert consultants. Enjoy step-by-step guides, weekly Q&A sessions, and full access to our AI workflow archive.

    Canva Logo
    Claude AI Logo
    Google Gemini Logo
    HeyGen Logo
    Hugging Face Logo
    Microsoft Logo
    OpenAI Logo
    Zapier Logo
    Canva Logo
    Claude AI Logo
    Google Gemini Logo
    HeyGen Logo
    Hugging Face Logo
    Microsoft Logo
    OpenAI Logo
    Zapier Logo

    Summary

    In this comprehensive tutorial by Codesistency, beginners can learn to build a fullstack note-taking application using the MERN Stack, which includes MongoDB, Express, React, and Node.js. The video takes viewers through every step, starting from setting up the environment, building the backend with an API, creating the frontend with React, and finally deploying the application. Along the way, learners are introduced to essential web development concepts such as HTTP methods, rate limiting, and the differences between SQL and NoSQL databases. The tutorial ensures that by the end, participants can showcase a live project on their resume.

      Highlights

      • The tutorial starts with setting up the backend using Node.js and Express. πŸ› οΈ
      • You'll learn to build and test a RESTful API, handling requests, and connecting to a MongoDB database. πŸ—„οΈ
      • The frontend is crafted with React, focusing on components, state management, and UI libraries like TailwindCSS and DaisyUI. 🎨
      • Deployment of the application includes using Render.com to host the backend and frontend together. πŸ–₯️
      • Security practices such as environment variable management and hiding sensitive information in a .env file are thoroughly explained. πŸ”

      Key Takeaways

      • The MERN Stack is an excellent choice for beginners due to its JavaScript-centric approach across both frontend and backend. πŸš€
      • You'll learn to set up a fullstack application from scratch, covering databases, server setup, and client-side development. πŸ“š
      • Understanding HTTP methods and status codes is crucial for effective API development and error handling. 🌐
      • Implementing rate limiting is a great way to secure your application from potential abuse. πŸ”’
      • With modern tools and services like Render and MongoDB, deploying an application is simpler than ever. 🌈

      Overview

      The journey begins with understanding the basics of the MERN stack. MongoDB, Express.js, React, and Node.js all play a crucial role in building the fullstack application. The instructor makes it clear that no prior knowledge of the stack is necessary, as the tutorial gently guides learners through each component.

        As viewers delve into the backend, they learn how to create endpoints and manage data with MongoDB. Express.js simplifies routing and handling of requests, while rate limiting is introduced as a security measure to prevent API abuse, showing the importance of securing web applications.

          The frontend development leverages React’s component-based architecture to create a responsive UI. Styling with TailwindCSS and DaisyUI makes designing intuitive and fun. Finally, learners deploy their applications using Render.com, solidifying their understanding of fullstack development by having a fully functional application live on the internet.

            Chapters

            • 00:00 - 01:18: Introduction This chapter introduces the tutorial's objective of building a beginner-friendly fullstack note-taking application using the MERN stack, which includes MongoDB, Express, React, and Node.js. The instructor assumes no prior knowledge of this technology stack and guides users through the process from scratch. The tutorial starts with constructing the API and testing it to ensure functionality before progressing to the front-end development with React. The end goal is to build a complete note-taking application.
            • 01:18 - 01:54: Setup and Configuration In this chapter, the tutorial focuses on creating a notes application that includes features such as adding notes with titles and descriptions, as well as updating and deleting them. The app is designed to be fully responsive. The chapter will guide through deploying the app for a live resume link. It is aimed at beginners, covering topics like building an API, understanding common HTTP methods, various status codes, the differences between SQL and NoSQL databases, and implementing rate limiting.
            • 01:54 - 04:19: Frontend Setup This chapter introduces the course, aimed at teaching the concept in the most beginner-friendly way. The introduction highlights an advanced 100-hour course offering where learners can build over 20 premium projects, including clones of popular applications like Netflix and Spotify, and even mobile apps.
            • 04:19 - 09:59: Creating Pages and Components The chapter instructs viewers to install Node.js from the official website and to use VS Code as a code editor to follow along with the tutorial.
            • 09:59 - 14:55: Implementing API Functionality This chapter focuses on structuring a project with separate folders for backend and frontend development. It highlights the initial steps in implementing API functionality, specifically building the backend first, followed by the frontend using React.
            • 14:55 - 21:00: Deploying the Application In the 'Deploying the Application' chapter, the focus is on building the React application from the front-end folder. Before diving into any coding, the author has prepared diagrams to help visualize and enhance the tutorial experience. These diagrams are not overwhelming and are freely accessible through a link in the description. The chapter hints at working with the MERN stack and sets the stage for further exploration.

            MERN Stack Tutorial for Beginners - Deployment Included Transcription

            • 00:00 - 00:30 In this tutorial, we are going to build a beginnerfriendly fullstack note-taking application using MongoDB, Express, React, and Node aka the Mstack. I will assume you don't know anything about this tech stack and as if it is your very first time building an application with it. We are going to start by building our API. Then we will test it out to make sure everything is working as expected. Once we are done with it, we will get into the front end with React and complete the entire tutorial. So this is a note-taking application
            • 00:30 - 01:00 where we can create notes with a title and description and then we have update and delete actions and this application will be completely responsive and at the end of this video we will deploy the app so that you can have the live link on your resume. This tutorial is completely beginnerfriendly. So you will learn how to build an API, what are the most common HTTP methods, the status codes and the difference between SQL and NoSQL databases. and you will even learn how to implement rate limiting which is a
            • 01:00 - 01:30 concept that you almost never see on a beginnerfriendly tutorial. But in this video, we will learn it in the easiest way possible. So that's the entire course. If you're ready, let's get into it. Just before we get started, if you'd like to build more advanced projects with this tech stack, we have a 100hour course with more than 20 premium projects such as building a Netflix clone, Spotify, Tinder, and even mobile applications. If you're interested, you
            • 01:30 - 02:00 can find the discount link in the description. Okay, so let's get started. Now, to be able to follow along with this video, you have to install Node.js. So, go ahead and visit nojs.org org and download the long-term support. Once you have done this, uh you should be good to go. And then for the code editor, I'll be using VS Code. Um if you want to have the same workspace as I do, maybe you could install this or use whatever you would like to. Okay, once you have done this, just go ahead create an empty
            • 02:00 - 02:30 folder on your desktop and just drag and drop it to VS Code. Right, you can call this anything. This is the name that I came up with. Now we are going to need two different folders. One for the back end and then the other one for the front end. So in the backend folder we will build the API and under the front end we will build the react application. So first we'll get started with our API. Once we have built everything uh everything related to back end we will
            • 02:30 - 03:00 jump into the front end folder and build the react application. And before we write any code, I have prepared some diagrams that I'd like to go over. Now, it's not really that much. I promise it's not like bunch of different slides. Not at all. This is something something that we would need to visualize uh visualize some stuff and really enjoy the entire tutorial. You can find the link in the description. It's completely free. Okay, so let's get started with the mer stack. The question is what the
            • 03:00 - 03:30 hell is the mer stack in the first place? Probably everyone knows this already but M stands for MongoDB. E stands for express, React and Node. Now MongoDB is our database that we'll get into in a second. Express will be the web framework. We'll get into it in a second as well. React will be the front-end library and Node.js is the runtime. So the beauty of this text stack is that both in the front end and
            • 03:30 - 04:00 in the back end we are using JavaScript right you don't really need to learn any other programming languages other than JavaScript all you need to do just learn JavaScript and you're good to go on the front end we'll be using React and on the back end we'll be using NodeJS okay so let's try to break this down a bit this is what I have prepared right on the right hand side Okay, so MongoDB is the database and to put it simple, you already know this, but it is a place
            • 04:00 - 04:30 where we store the data, right? That's it. Let's keep it simple and move forward. So, we'll be using MongoDB and we'll get into the details in a couple of minutes. And then the express will be our web framework just like I said a couple of seconds ago. And a web framework is a readytouse toolbox for building web applications faster and more easily. So you don't really want to reinvent reinvent the wheel from scratch, right? Why why do you want to
            • 04:30 - 05:00 use a web framework? So it'll save a lot of time. It'll make your code cleaner and more organized because they have built everything uh like from scratch but someone else built it and it's really stable, right? Something like Express which has been used for years and years. So it's completely clean, stable, working perfectly. This is what we'll be using. And then it'll handle common tasks like routing, error handling, and everything that you can
            • 05:00 - 05:30 think of. And then we have the Node.js, which is going to be the JavaScript runtime. Now, what does that mean? Basically, it'll allow you to run JavaScript on the server. Normally, you can run JavaScript on the client, such as in your browser, but thanks to Node.js, we can run JavaScript on the server. And I hope that makes sense. And then finally, we have the React, which is going to be our front-end library, our favorite front- end library. And we'll get into the details, but I assume
            • 05:30 - 06:00 you know the basics of React like super basics like components, maybe use state, and use effect. That should be it. Okay. So, now that we know the basics of NodeJS and Express, let's get started with it and build a really simple application. So, I'll visit VS Code under the back end. Uh first I'll open up my terminal. The shortcut is command J or control J. So I will cd under the backend folder. So if you just type BA or B A or only B and press tab, it's
            • 06:00 - 06:30 going to autocomplete. And then you can say uh initialize a Node.js application. So we can say npm init-y which is going to give us a package JSON file where we can install different packages. So the first thing I'd like to do clear my terminal and install express. So I'll say mpm install express. Now if you type this out by default it'll give you the express version 5. But I'd like to use a specific version which is going to be 4
            • 06:30 - 07:00 let's say 4.18.2. So we'll be using some specific versions so that if you're watching this video in the future it should not be obsolete. So you can still follow along with me the exact same way that I do. So nothing will break in the future. And the Express version 5 just came out. Uh currently like everyone still uses Express version 4. So don't ever feel like this video is outdated. Not at all.
            • 07:00 - 07:30 Express version 4 is actually the version that currently everyone uses. Every single codebase has it. Okay. So it is not it's not obsolete at all. Not outdated, nothing. It's like up to date. Okay, let's go ahead and install it, which is going to give us a package log JSON as well as the node modules. So, these are the things that you don't really work with at all. Um, let's try to create a file. The convention is to either call them like index.js or let's
            • 07:30 - 08:00 say app.js and we even have server.js. These are the conventions. I'll be going with the name server.js. Okay, let's create this file and let's import express. Now, I'd like to use this syntax where where I can say import express from express. Um, you cannot really use it by default. Let's try to run this file. Actually, I'll show you the warning and then we'll fix it. Let's say const create an express
            • 08:00 - 08:30 app. Actually, this should be app. Let's say express call the method. And now we can listen on a port. I'll say app.listen listen you can put any port I'll be going with this value so I would say just follow along with me and then once we start listening we can put a console log let's say server started on port let's say 501 okay now we would like to run this
            • 08:30 - 09:00 file you can open up your terminal and you can just say mpm run serverjs this would not work Obviously, so what you would like to do, let's just run this. This is something that does not work. Maybe you have seen something like mpm rundev in other tutorials. Now, by default, this is also not going to work. And I'll show you how we can make that work. But if you want to run this file by default, you would say run this with NodeJS. So, we would say node and
            • 09:00 - 09:30 then server.js. Okay. So, it says server started on this port. And we have a warning that I just mentioned. It's coming uh because we're using the import syntax. Now to be able to get rid of this just visit the package JSON and here put the type to be module. By default it is common.js where you need to use this syntax. So if you were to say express um require the express package. So this
            • 09:30 - 10:00 and this means the exact same thing, but they are just different syntaxes, right? So let's try to save. And we shouldn't really have any warnings if you kill it with Ctrl C and then run this again. Now we don't really have any errors. But if you want to use the import export syntax, you need to add the type to be equal to module. Now we don't really have that error if we try to run this.
            • 10:00 - 10:30 Okay, so that's the very first thing that I wanted to mention. Now, if you wanted to run this file with a script such as npm rundev, you would create this script. So this is the key. Let's put the key called dev. And then we would like to basically run this when we say npm rundev, right? So we will say delete everything here. We will say node server.js. when you say npm rundev behind the scenes it'll run this
            • 10:30 - 11:00 part. Now let's run this. It is working as expected. So I know that we are going really slowly but I just want to make sure that we understand everything as we go. Now you can create more scripts if you really wanted to. So you can say something like hello. The key doesn't really matter. What matters is what you will run on the right hand side. So we don't really want to have something like hello. Instead we'll have something called start. This is something that we'll get into in a second. But first, I'd like to just save this file and get
            • 11:00 - 11:30 into the server.js file. So, here on the back end under the server.js, we are going to build an API. I'll explain what that means. But first, let's just build a really simple route and then we'll understand what that does. So, here I'd like to say something like app.get method. So listen for the let's say slash API slash I don't know let's say something like notes here once we get the get request we would like to run a
            • 11:30 - 12:00 function which is going to take the request and response so say request and response so these are the things that express will pass by default you can take those values and maybe send a response let's say rest dot send we can say something like you five nodes. Now let's try to test this out. We need to kill this and run it again because we have changed we have changed something under the server.js.
            • 12:00 - 12:30 So I'll go ahead and run this once again. Let's try to send a request to localhost and our route and our port which is 501. Let's say 501 slash API/ nodes. Now we need to type this out because this is what we are listening to right with a get method. So I'll go ahead send a request. This is the output. This is the response that we got. So believe it or not, but
            • 12:30 - 13:00 we have just built our very first API where we where we are listening for a get request and we are handling it properly. Now obviously this is not what we would like to do. This is just for testing purposes. But let's see what is an API in the first place. And just before we get into the APIs, let's see how a full stack app work in the first place. So you would have your client which is the front end and we have a server, right? Which is our back end. And then we have a database where we
            • 13:00 - 13:30 store the data. So from the client user would send a request here. Let's say they want to delete a post, right? They click this button. They would send a request to the server. So we got the request. Now we would like to delete it from the database. the back end will delete it and send a response back like success. Here you go. This post has been deleted and the UI will be updated. So this is what we call the request and response life cycle, right? You send a
            • 13:30 - 14:00 request and get a response back. That would either successfully done or it would fail. So this is how a full stack application works simply. But now on the server there are one more thing that we need to talk about which is the API. So what's up with API? It stands for application programming interface which is absolutely doesn't make any sense but in simple terms it allows two different applications talk to each other right so you can think of it like a waiter this
            • 14:00 - 14:30 is a pretty classic analogy that we'll go through but I think this explains everything uh like perfectly really clearly okay so we have the waiter which is the API let's say you visit a restaurant where you would like to send a request, right? You are the customer. You send a request. Let's say you want to get a chicken. Uh once it is ready, you will get it as a response back, right? So, I just changed the color. You send a request and get a response back.
            • 14:30 - 15:00 And we have this man in the middle, which is the API. So, that was the analogy. And in real world, you would send a request from your browser, right? You would send a request and get a response back, either success or error. But in either case you would get a response back. So I really hope this makes sense and this is actually what we have just built in simple terms. So we have the end user which is here on the browser. It is us. We sent a request to this endpoint to this URL and we got a
            • 15:00 - 15:30 response back. Right now in real world and this is what we'll be doing in a couple of minutes. you would actually send a request uh let's say here before you send a response you would interact with your database right you would send a request like let's say delete a post or delete a node and maybe you would have another endpoint where you would like to create a node right these are the things that we'll be doing uh but I hope for now
            • 15:30 - 16:00 everything makes sense this is what we have built in simple terms now the question is can't we just get rid of this API the man in the middle can't we just interact with our database uh from the let's say from the front end why do we need it in the first place why do we need an API so the answer is we definitely need an API no matter what so you cannot really just access to the uh database you cannot just interact with the database from the front end now why
            • 16:00 - 16:30 this is the case so imagine this like 90% % of your users will be goodhearted, right? They'll be good customers. But some of them will be really really malicious. Let's even put an emoji. So, they'll be really malicious and they would like to kill your entire server, right? They would like to delete everything that you have in the database or maybe they would like to access everything other than just notes. Let's say they would get access to every
            • 16:30 - 17:00 single password so on and so forth. So you cannot really trust to the front end to the client. Instead, you would have a waiter which is someone that you can trust and it's only going to do the things that you want to happen, right? So just to give you another example, let's say you get rid of the API which is the waiter. Now your malicious user can just walk into the kitchen and steal something, right? It can like they can even break the entire kitchen. So that's
            • 17:00 - 17:30 why you always want to have the man in the middle which is the API. So I hope that makes sense. Now there are different types of APIs. The one that we are interested in is the rest API which is the most popular one. Uh like this is what we're going to be building in this video. You can take a look at the other types of APIs but 99% of the times you will be working with a REST API. Okay. Now it like it uses HTTP methods which
            • 17:30 - 18:00 are get, post, put, delete and there is more like patch uh but these are the ones that you'll see the most right 99% of the times this is what you'll uh encounter and the names are pretty self-explanatory. So when you send a get request probably you want to get some data right to give an example you would like to get some posts on Instagram. When you want to do so, you would send a get request. And in this example, we sent a get request to fetch our notes,
            • 18:00 - 18:30 right? And if you want to create one, you would send a post request. If you want to update, you would send put request. And then to delete something, you would send a delete request. And here in the back end, we are listening for the get request. Right? This basically says if we get a request a get request under API and notes just go ahead send the notes right let's delete this comment okay so here you got a get
            • 18:30 - 19:00 request and you would send the notes right and if you want to create something let's say you would listen for the post request and user would send you a post request uh this part could be anything you can just say API slash Hello, anything that you wish but most of the time it should be something that makes sense here. Let's say they would like to create the node and then like instead of this we'll get into it. We'll build it with actual
            • 19:00 - 19:30 actual code but these are just examples for now and then you could create let's try to duplicate this. So you can create the put method right and it's actually autocompleting. So we have patch we have delete so on and so forth. We'll get into every single one of them. Uh, but this is basically what we have. And then there are some status codes. So it starts from 100 all the way up to 500 that we'll get into. I have bunch of
            • 19:30 - 20:00 different examples that we'll go over. So any status code that starts with 100 isformational. This is something that you are not really encountered that much, but just know that 100 status codes areformational. And then anything that starts with 200 is a success message and 200 itself is okay like everything went everything worked as expected right everything went successfully and then 201 which means something created successfully so let's
            • 20:00 - 20:30 say you created a note you would get 201 from the back end right let's try to actually do it here under the get request just before we send the response you can Okay, resa status we can just say 200 it is done successfully. If you had the post request, you could say 201. Let's say your node has been created successfully. Okay, so I hope that makes
            • 20:30 - 21:00 sense. 200 anything includes 200 means success. And these are the most popular ones that you should keep in mind. And then we have 300, which stands for redirection. Again, not something that you that you would encounter that much, but I just put it here so that you can have it in your notes. So, let's read it out loud. The 300 status codes are for redirection, meaning the server is telling the client, "Hey, the thing you are looking for is somewhere else."
            • 21:00 - 21:30 Let's take a look at an example. Uh on the 301 status code, which means removed permanently, sorry. Okay. So, let's take a look at the example. Let's say your site changes from httpacample.com to https.acample.com. So you just change something and then you would set up a 301 redirect so that the visitors and Google would know to go to the new one, right? To go to the new one. Again, this
            • 21:30 - 22:00 is not something that you will encounter that much, but just keep this in mind. Um, so yeah, you can have this in your in your notes. All right. And then finally, we have the error status codes which are 400 and 500, right? The ones that include 400 or 500. Now, let's see. I'd like to just immediately show you an example before we read it. So, we have 404, the most popular error message, which means not found. Let's try to see it in action immediately. So, I'll say
            • 22:00 - 22:30 API/hello, which is something that we don't really have. We're going to get 404 error. Now if you say inspect and visit network refresh this page and just make sure you select the fetch xhr or maybe even all. Okay, just refresh you. You got 404 status code, right? It means you don't really have this route. Okay, so once you have 404 it means there are some errors on the client. So, think of
            • 22:30 - 23:00 it like you as the client, you as the user, you just messed something up, right? You sent a request to a wrong URL. Or maybe you are unauthorized, but you try to create something. So, to give an example, let's say you are on Instagram without logging in, you cannot share something. If you try to do so, you're going to get 401, which means unauthorized. Okay? So that means the client errors happen when the problem is
            • 23:00 - 23:30 on the user side meaning your browser or your application made a bad request. These are the most popular ones that you should keep in mind. So 400 bad request it says like this is invalid. 401 unauthorized you must be a login. 403 forbidden you are not allowed to access this site. 404 not found. And 429 too many requests. So, we'll see this one as well. Uh, this is something that I'd like to leave it later in the video. And
            • 23:30 - 24:00 then finally, we have the 500, which means the server errors. And you would get these server errors when something goes wrong on the server side. So, even though you made a valid request, just because server couldn't make that work, you will get a 500 status code. So, you can think of it like the server tried but it failed. And the most popular status codes are right here which are 500 and 503. So 500 is a general error
            • 24:00 - 24:30 that says internal server error, right? So something is broken on the server side and 503 which means service is unavailable where the server is temporarily down. It is overloaded. It is like there are some maintenance anything you name it. It is just down right. you cannot access it. And to give you an example, this is the 5 and 503 error page for GitHub. So currently
            • 24:30 - 25:00 GitHub is up and running, right? You can get the response, but if it was temporarily down, you would get this output which gives you 53 status code. Okay, so I hope everything makes sense. Now, I know that we went really slow so far. Um, I just wanted to explain everything that you would need to be able to follow along with this video. Uh, we'll get into even more details just in a couple of minutes. But for now, this is what we would need to get started with it. And I'll go ahead clear
            • 25:00 - 25:30 this up. Let's say for now, we can have this get request only. It is working as expected. So for now, if these are the things that you have seen for the very first time, maybe you can watch this section once again. So from start up until now and maybe you can go over these diagrams. I think these are really important details that you should know that you should keep in mind. However, if it is confusing that's completely fine. It is too much information at the beginning but we are going to get into
            • 25:30 - 26:00 the tutorial. We're going to write a lot of code so everything should make sense. I'll see you in next section where we'll work we'll work on our codebase. All right. So this is where we left. Now there is something really really annoying in our code. Let's try to fix it. And before we fix it, let's try to understand what that is. Now we have you got five nodes as the response. Let's try to see it in action. Uh let's try to fix this. I'll say visit nodes, we got this response. But now every single time
            • 26:00 - 26:30 I update this, let's say I'll say 10 notes. If I save and try to refresh this page, I'll still get the old result. which means every single time I have a change in my code, I need to kill my terminal and make sure you're under the back end and I need to run this all over again which is really annoying right now. If you take a look at the result, it will be updated. But this is not something we would like to have. Instead, every single time once we save,
            • 26:30 - 27:00 once we change something, this should restart. So for this, we are going to install a package. Let's kill the terminal. clear this up with command K or clear. If you're on Windows, you can say cls. It should it should clear the terminal. So I will say mpm install. The package name is nodemon. And I'll say dash d which means install it as a dev dependency. So let's go ahead and run this. Now we will visit package.json. We
            • 27:00 - 27:30 got the nodebon. Here we go. And we will say run the server.js JS with nodemon not node let's say nodeman. Now if you save and try to say something like mpm rundev it'll do the exact same thing but instead it'll run it with the nbman. So it is going to listen for every single change. It's going to watch it. Let's say we just said it's going to be 20. Once you save it'll be restarted so that
            • 27:30 - 28:00 you can get the latest output without killing your terminal. Okay, so I hope that makes sense. This is something that you should definitely do in development. Otherwise, it's not really going to be comfortable. Okay, so now that we understand the nmon and how to use it, um I would like to add another script which is going to be for production. So this dev basically means development, right? You would like to run this while you're developing the application. This is exactly what we are
            • 28:00 - 28:30 doing currently. We are changing our code really often, right? So that's why we run this app with the development script. But once we deploy the application, we would like to run with a command called start where we don't really want to use node one. Instead, we'll say go ahead run the server.js file with node. So that you don't really listen for the changes. We don't really need it. Right? Once we deploy the app, probably we will never change the code. Even if we change uh the application
            • 28:30 - 29:00 will be deployed again. So I know that it might sound complicated but I hope you get the point. We will see this in action once we get into the deployment. So it's not going to be really complicated for now. Just know that this is something that you would like to run in development just like what we are doing because currently we are developing developing the application. Sorry. And then once we deploy we'll be using the start command. Okay. So this is something that you should keep in mind as a beginner. Okay. So this is
            • 29:00 - 29:30 something that you should keep in mind. Um let's kill the terminal and go into the server.js file. Let's try to define some of our routes and then we will get into the database in the next section. So I just said let's define some of our routes. You might be asking what does that mean? Basically this is a route that we have. We are listening with a get method under this URL. Once we got the request we will do something calculate and send it back to the client. So this entire thing what we
            • 29:30 - 30:00 call a route. There's also what we call the endpoint. Something really really common that you'll hear. Uh let's read it out loud. An endpoint is a combination of a URL and HTTP method that lets the client that lets the user interact with a specific resource. So this is our very first endpoint that we have built. Let's try to duplicate it. If you wanted to, you can type this out. Let's do it actually. Let's say user wants to create a note. they would send
            • 30:00 - 30:30 a post request to slash API slashnotes and then we would get the request and response objects and then we would for now let's say res status of 201 and remember this means something created successfully and then we can send a message you can either use the send or like this would actually send a response under the HTML, but we
            • 30:30 - 31:00 would like to mostly send a JSON response. So, I'll say JSON and let's send a message like post created successfully. Okay. And then we can duplicate this. We'll add another route where they would like to update a note. So, we'll say it's going to be 200. Let's say post updated successfully. So
            • 31:00 - 31:30 these are for testing purposes. Of course, we will interact with the database a bit later in the video. Okay. Now, one thing is really important right here. If you want to update something, you would you would like to know which post that is or which node that is, right? You cannot randomly just go into the database and update something. You would like to get the ID of that specific node. So user will send it. So
            • 31:30 - 32:00 let's say they will send a request to localhost 501 / API/ nodes. Let's say the node that they'd like to delete has this ID. So they will send to anyone. You will get that ID and you will delete that one specifically. Now this value could be anything, right? You don't really know that. So that's why we say this will be dynamic. Okay, I hope that makes sense. Since we are updating something, we'll say put method and let's create one more
            • 32:00 - 32:30 for the delete for the deletion. If we want to delete something once again, we would like to get the ID so that we know which node that we are trying trying to delete. I'll say node. Let's update them. Node deleted successfully. Okay. So for now that's going to be that's going to be it for our endpoints for our routes. In the next section we are going to in the next
            • 32:30 - 33:00 section we are going to integrate our database which is going to be MongoDB. Okay. So this is where we left. Just in the previous section I said that we'll get started with the database but I'd like to take a quick break and organize this codebase. So let's make this a bit more cleaner by following the best practices. So this is how you would do as a complete beginner right without knowing anything you would just put your entire code under the server.js which is fine but if the project if the project
            • 33:00 - 33:30 gets really large this is going to be unmanageable. So what you would like to do take all these functions routes and put them under different folders and files. Because if you think about it, maybe this function will be around 50 lines of code. This will be 70 lines of code. So on and so forth. This file will get 1,000 lines of code and you cannot really manage it. So what you can do instead, let's delete these spaces. We
            • 33:30 - 34:00 can take every single one of these routes under different folders. So I will create one called routes. Um let's create a file called nodes route or let's say nodes routes.js. You can call this anything but this is some of the one of the conventions that we have. Okay. So at first this will look a little bit complicated but please follow along with me for the next 2 minutes and then everything will make sense. So here in
            • 34:00 - 34:30 this file you would like to import express because we'll be doing something. Let's say import the express and we would like to create a router. Let's say use express.outer. Okay. Just make sure that R is capitalized. And then we can say export this one. I'll say export default router. Now we can put our endpoints. So first let's just save. We'll add something here. and let's try to uncom or comment all of them. Now just before
            • 34:30 - 35:00 I comment this I'd like to mention something. So here in this file if you have realized every single one of these routes has something in common which is / API/notes. So instead of typing this out on every single route we can just remove it and only type it out only once. Okay. So I'll just comment this out and I'll say just maybe at the very beginning right after the app and I'll
            • 35:00 - 35:30 delete this comment. We don't really need it. If you wanted to you can put it in your notes but I'll delete that. Okay. So I'll say app dot use. So you would use dot use without any methods because we will take these methods and put it under the routes. So let's say if we got a request to / API/nodes if it starts with this one we would like to hit this file which is something that we can import let's say import nodes
            • 35:30 - 36:00 routes from let's go into the routes and visit this file just make sure to put the js at the end okay so I'll say get this file now let's take every single one of M I'll basically cut this save and go into this file. Now let's try to create these. So instead of app.get you'll say router.get and you can put the exact same thing but we don't really want to
            • 36:00 - 36:30 put this / API/ nodes because it is already prefixed. Again this will make sense. Just for now follow along with me. We'll just say only slash and then we can get this method and put it right here. Let's try to delete the comments. Okay, so that's it for the very first route which was this one, right? Where we can get the notes. Let's say you just fetched the notes. Okay,
            • 36:30 - 37:00 we'll do the exact same thing for these ones. If you wanted to, you can pause the video and do so. I'll say router.post. Again, instead of app, you would say router.post. You don't really need to type this out. It is already added. We'll just say slash. And then we'll get this part which is our handler function. Let's delete the comments. Save. And I'll be doing the same thing for these ones. Let's copy it. Paste it. Probably this is what we
            • 37:00 - 37:30 should be doing until now. Let's say router. But just delete this part because it is already included, right? / API/notes. We already have this. It is prefixed. But we would like to add the slash ID at the end. Now this should be making sense completely. And then I'll get these two as well. We don't really need to put we just put that. And then let's say router delete. And again we already have
            • 37:30 - 38:00 this. So we can just leave this part. Okay. So let's save fill the left hand side and put them side by side. Let's see what we have just did. So it's really really clear what we have done right. We basically take all those previous endpoints and prefix them with / API/notes. So if you send a request to / API/notes you're going to hit this and you would get this response. If you hit
            • 38:00 - 38:30 with a post request you would get this response. If you hit SL API/ nodes slash sum id with the put method, you would get this response and same for the delete. I hope all makes sense, right? Let's actually test this out. If we just visit this part with a get request, we should be able to get this response. So I'll go right here. Um I'll say / ai/nodes. Let's refresh. We just fetch the nodes. Let's try to say it'll be SL
            • 38:30 - 39:00 API/nodes slash something. Let's do it. Say if you refresh now, this should say cannot found. But let's say slash something. Okay. So I hope that makes sense. We just link them by prefixing this. So that was the very first thing that we have done. Now again what we can do even like even organize this even
            • 39:00 - 39:30 more because if you think about it these functions can get really large right um what we would like to do just take them and put as a separate file and folder this is what we call a controller right we have bunch of different controllers so this is the first one second one so on and so forth let's create the controllers and these controllers will be for the node notes. I'll say notes [Applause] controller.js and then basically we will
            • 39:30 - 40:00 cut them one by one. So I'll just cut this. Let's paste this in and let's call this as a function. So you can create it as a as an arrow function. Let's say const get all nodes. Okay, this is the function. Now we can export it. Let's say get all nodes. And make sure to put the js at the end. If you wanted to, you can make this as a regular function as well. Let's do it
            • 40:00 - 40:30 pretty quickly. I'll say we will export this function. Let's say export function get all nodes. We will delete this part and this one. Okay, this is the other way of writing it. Let's just have it as a function or arrow function. It doesn't really matter. And you can mark them as async if you really wanted to. It's just a regular function, right? So you can call it as async or not depending on what you'll be doing with it. Okay, now
            • 40:30 - 41:00 we can get this one. I know that we are going slowly, but I just don't really want to rush. Let's just go slowly. I'll go ahead duplicate this one. Let's say create a note or let's just say create note and I'll just paste what we have copied. I'll just leave the response. Okay, let's do the same thing for this one. I'll say create node. Import it from this file. This is to update a node.
            • 41:00 - 41:30 I'll say export function past this in. Give it a name like update node. And let's try to do the same thing for the delete. Say delete node. And I'll get the response. Let's cut this and paste this in. Okay. Build like to import them now. I'll delete this entire
            • 41:30 - 42:00 thing. I'll delete the extra spaces. Okay. So, what we have done is basically take these controllers and put it under the specific file. So, everything should be working as exactly as it was before. Now the beauty of this codebase is that later later at some point let's say you want to add some stuff related to products. You can basically create this route and create this file. Let's say
            • 42:00 - 42:30 it'll be product routes. So you can add your product routes under a specific file. Let's say you will have another one for let's say posts. Maybe you are building some social media application. You would add let's say something related to payments. you would add something like emails. So you get the point. This file otherwise would be incredibly large but now it's just only five lines of code where you just separated every single service into
            • 42:30 - 43:00 its own file. Okay, so I hope all makes sense and we even even more optimize it by creating this controller file. So that's kind of it for this section I was going to say but one more thing the best practice one of the best practices is to create a source folder. So you can create this one and put everything related to application under the source. So just go ahead put the controllers and the routes as well as the server.js
            • 43:00 - 43:30 file. But if you do so you will notice that your application will crash. Now why is that? Can you spot? Well, it's because under the scripts you say run the server.js file, but now it is under the source folder, right? It's not under the back end. So, you would like to say it's under the source. Let's fix this one as well. And you don't really have to fix this part, but let's be consistent. And let's say our main entry
            • 43:30 - 44:00 point is the server.js file, which is under the source folder. Okay. So if you save, kill the terminal and run this from scratch, it should be working properly. Okay. So that's going to be it for the kind of the optimization section. So with that in the next section, we'll get started with the database. All right. So in this section, we're going to get started with the MongoDB, which is going to be our database. It's completely free to get
            • 44:00 - 44:30 started with. You don't really need to pay anything or you don't even need to provide with your credit card. So head over to mongodb.com and create an account. I have already done this. So I'll go ahead and log in. I have logged in with my Google account. It'll just redirect me to the dashboard. Okay. So we will create a project in a second. But first let's go over these nodes that I have. We basically have three different comparisons between SQL databases versus NoSQL databases. So
            • 44:30 - 45:00 MongoDB is a NoSQL database. And then we have some SQL databases like Postgress or let's say MySQL so on and so forth. And for the NoSQL databases we have other examples like Cassandra or let's say Neoforj so on and so forth. Okay. So in SQL databases data is stored in tables with rows and columns. So it is like a spreadsheet. And then in NoSQL databases, they store data like JSON or
            • 45:00 - 45:30 key value pairs which is good for changing data shapes. So the SQL databases are a bit more strict when it comes to how you store the data. But NoSQL databases are a little bit more flexible. And then the SQL databases use SQL language. So you would use things like select, insert, so on and so forth. But when it comes to NoSQL databases, they would use a query language. And each NoSQL database has its own way of
            • 45:30 - 46:00 querying, often simpler and faster for certain tasks. And we're going to see this once again. And then finally, you might be asking when do we use a SQL database and when do we use a NoSQL database? So you would use a SQL database whenever you need like complex queries or let's say you have a lot of relationships in your application. So to give an example, let's say you're building a really large social media application where you have bunch of different relations between your data,
            • 46:00 - 46:30 right? So this could be a perfect example to use a SQL database or let's say you are building a really large or just a bank application, right? Everything has to be really strict and you have bunch of relations. And when it comes to NoSQL databases, so it is great for fast changing data or huge amounts of data. So these are the things that you can keep in mind. But as a beginner, it doesn't really matter if you use MongoDB or Postgress or MySQL, right? All you have to like all you want at the
            • 46:30 - 47:00 moment is to have a place where you can store the data and interact with it, manipulate it, so on and so forth, right? Okay. I hope that makes sense. So with all this in mind, we can head over to dashboard and create a new project. So here I'll just say view all my projects and then I'll create a new one. Let's call this as thinkboard. Let's say next. Create the project where we need to create a
            • 47:00 - 47:30 cluster. So we'll go with the free plan. Okay. So let's say create a deployment. I'll leave everything as it is. Okay. Come on. Let me go over this AI check. Once it is done, you will be redirected to this page. Let's copy the password. So just make sure you copy it. Let's say create the database user and then choose a connection method. So we will connect to our database from our NodeJS application. So let's select the
            • 47:30 - 48:00 drivers option. Okay. So the first option is to select your driver and version. We'll just leave them as it is. The second step is to install MongoDB. But instead of using the MongoDB driver, we'll be using something called mongus. So let's search for it. Okay, we'll be using this. It's a lot more cleaner and it'll give some strict rules where we can have our schema the schema validation which is something that we'll get into. So we can skip this step. And
            • 48:00 - 48:30 finally once it is done like they will they will provide you a connection string. Now that we got this we can copy it. I'll have the password open so that it is included. I'll just copy it. If you cannot see your password, it would look like this. And you would delete this part. Paste your password that we have just copied a couple of seconds ago. But probably you have this option. So go ahead turn this on. Copy it and paste it to your codebase. For now, just put it under the
            • 48:30 - 49:00 server.js. We'll be using it. Okay. So we can just say done and we can actually get started with it. Now just before we connect to this database I would like to go under the network access. So currently this would include your current IP address. From this IP address you can connect to this database. But we don't really want to get any errors. So I'll say add an IP address where we can access from anywhere. Right? So I'll say confirm.
            • 49:00 - 49:30 This will take around 10 to 15 seconds. Once it is done, it should be active. Okay, so it's done. It's active. In my case, it took around 30 seconds. But now we are good to go. Let's go under the clusters. Let's say browse collections. But obviously, we don't really have a like we don't really have anything, right? Zero databases and zero collections. So let's use this connection string where we can connect to our database. But before we do so, let's open up the terminal. Let's kill the back end. Just make sure you are
            • 49:30 - 50:00 under the back end. And as I said, we'd like to use mongus. So I'll say mpm install. You would say mongus. And you would press enter normally, but let's use a specific version as I said at the beginning. So that if you're watching this tutorial at a future date, like it should still work as expected. So I'll go with zero sorry 7.0.3. We'll go with this version. Let's install
            • 50:00 - 50:30 it. Okay. And now we can clear the terminal and say mpm rundev. Okay. Now let's copy this connection string and try to connect to our database. I'll just cut this. And to be able to connect to my database, I would like to create a specific folder where we can put our configurations. So I'll say config and let's say db.js file. Here we'll create a function where we can connect to the
            • 50:30 - 51:00 database. So I'll say const connect connect DB and this will be an async function let's say and we'll have a try and catch block. In the try we would like to connect our database successfully. But if we got some errors we'll hit the catch where we can just add a console lock. Now, first thing I'd like to do is importing. Let's say import mongus from the mongoose package. Okay. So, it's
            • 51:00 - 51:30 really easy to connect your database. All you have to say mongus.connect and then put your connection string. So, I'll just paste this in. Now, this will take a little bit of time. So, we would like to await this. And then once this is done, let me just kill the left hand side. I'll say console log. Let's say MongoDB connected successfully. Okay. And in the catch we
            • 51:30 - 52:00 can add another console log. Let's even say console error. I'll say error connecting to MongoDB. And then we can put the error message or let's just put the error itself. And now let's try to save this and try to call this method. So I'll say export this from this file and under the server.js we can just call that method. So I'll say call the connect DB and just make sure to put
            • 52:00 - 52:30 the js at the end. Now let's save and take a look at the terminal. Okay, MongoDB connected successfully. Now if you try to break this, right, I'll just delete the some part some part of the password. Now it is wrong. Okay, here we can see we got an error. It says bad authentication. The authentication has failed. So we hit the catch block. As you can tell, it says error connecting to MongoDB. And then we would see the error itself. So I'll do Ctrl + Z, bring
            • 52:30 - 53:00 this back. And we are good to go. Now the other thing that you would like to do in the catch block, if you got some errors, you would like to exit the process. So you'll say process.exit and the status code is going to be one. Now one means exit with failure. Okay. But if you had zero that means success. But since we are in the catch block this is going to be one which means failure. Now let's save this code and take a look at our database. So
            • 53:00 - 53:30 I'll try to refresh this page. We should see some kind of a database or we cannot really see it because we didn't really create any data or any collections. But the problem that I'm trying to mention is that we didn't really give a name for our database, right? This is currently called as test. Okay. So if you don't put anything, your database will be test. But let's try to update it. I'll say notes DB and you would put your
            • 53:30 - 54:00 database name just before the question mark. So this is something to keep in mind. We just updated that. And once we create the database once it is visible in this dashboard I'll mention this once again we will see this name. Now you might be thinking this code is perfectly fine but it's not really because if you deploy this code to GitHub if someone opens up your db.js file they can see your connection string and they can use it like they can connect your database
            • 54:00 - 54:30 because they're able to see your username and your password. So what you would like to do cut this from here and put it somewhere else. And this is where the env file comes into play. So under the back end let's shrink everything. We will create the env file and we can put our connection string. So I'll say uri and let's say this will be equal to this value. We can delete the quotes. Okay. just paste this in as a as a
            • 54:30 - 55:00 string that you have just cut it. Okay, let's save. Now, how do we use this value? How do we get this uh key and then the value? So, to be able to use this, you need to get a package. Let's open up the terminal. I'll say mpm install. So, this is a package that allows you to get access to environment variables. So this is what we call an environment variable. By the way, now
            • 55:00 - 55:30 that we have installed the package, let's run the app. Um, so I think we are getting a deprecation warning. This is something that we can take a look at it in a second. For now, just ignore this. It's not really important and it has nothing to do with the MV package. So for now, just ignore that. We'll go under the server.js. Let's try to configure the env package. Now, why do we need it? So if you currently say console log process
            • 55:30 - 56:00 environment variable name now this will give you undefined in the terminal. So here you can see you cannot read this value. To be able to use it you need to say importv from the MV package. Let's type this out and then you would say config. Call this method. Once you have done this, you should be able to get that value instead of undefined. Right? Previously, it was undefined. But now we
            • 56:00 - 56:30 can get the value. And if you put this something wrong, let's just add 1 2 3. Okay, it's not going to work. It's undefined because you have to put this name. So now that you know how to access the environment variables, let's cut it from here and we will add it right here. So let me delete the spaces. I'll say process envongo uri. Okay. Now we are going to hide this
            • 56:30 - 57:00 file in GitHub so that no one can see our um our connection string. Right. This is now an secret environment variable. Okay. So I hope that makes sense. I'll just try to go over it pretty quickly once again. So we didn't really put our connection string as it is. Instead, we take it and put it under the env file. So that it is a secret. No one can see it other than us. It is only like it's only available locally in our machine. If we deploy our code to
            • 57:00 - 57:30 GitHub, we will hide this file with a get ignore file which is something that we'll do at the end of this video. So no one can see this value. Okay. So this is that file that you need for the secret variables. And to be able to use it, we have installed this package called DMV and then we call the config method to be able to properly use it. Now another convention is to get your port and put it under the DMV. So this is exactly what I'll be doing. I'll just say port all uppercase and I'll put this value.
            • 57:30 - 58:00 Now you don't have to do it but I would recommend it. So let's get this value. I'll say con port which is going to be coming from the env port and if let's say this is undefined we can add this fallback value. So if this is equal to false or undefined we will get this value. Now let's put this in. I'll just say use this port and we can add this dynamic value. So I'll just say add the port at the end. Okay. This is going to
            • 58:00 - 58:30 work as exa as exactly as it was before, but we just updated our code. Now, what's up with this error? I don't really know. I think it's because of the mongoose package. Maybe this version is causing this. So, what I'll be doing is kill the back end. Let's say npm install mongus at latest. Okay. Okay, now it's been
            • 58:30 - 59:00 updated. So in your case, just don't type at latest. Go ahead, put this version. Okay, so just say mpm install mongus and paste this in. It should update it. Now let's try to run the app. Hopefully we'll get rid of that error or the warning. Okay, now we don't really have that warning that we got previously. And for the env by the way, I think I just said mpm install.env. Go ahead add this at the end. If you have already done this, it's
            • 59:00 - 59:30 completely fine. Just do it once again. Add this at and the version itself and then you can start your back end. Okay. So server started and then MongoDB connected successfully. Now the next thing that we would like to do is to create a model. So let's try to create this folder called models and we'll have only one model that will be node.js. So this is one of the conventions where you capitalize the
            • 59:30 - 60:00 very first letter and you put it as a singular right so you don't say notes instead it is the node.js so we will create a model for the node because uh like let me show you the end result here we have some screenshots. So every single node has some values like a title, a description, right? This is the description of the note and then we have things like created at date and updated
            • 60:00 - 60:30 at. So these are the things that we would like to store and let's create the model so that we know which fields a note will have. I know that it might not make too much sense, but let's see let's see this in action. The first thing you would like to do is to import the mongus from the mongus package and then you would first create a schema. So let's say first you would create a schema and then second you would create a model based
            • 60:30 - 61:00 off of that schema. Let's see how that work. So first let's create the schema. I'll say const node schema. You can call this anything but this is the name that I'll have. I'll say new mongus schema and this wants you to add an object. So here we will put our fields. Let's say every single node will have a title which is going to be type of string. So let's just say type is going
            • 61:00 - 61:30 to be string and then we can say it'll be required. So every single node has to has a title. Let's say required will be equal to true. And then the other fields that we would like to have is the content which is the description. I'll call it as content. You can call this anything but I would say just follow along with me. So put the content let's say again type will be string and then it'll be required as well. So I'll just duplicate that and
            • 61:30 - 62:00 put this in. Now the other thing we would like to have is the created at field so that we can put the created at right here in the note. So you can type this out the like manually right you can say created at and put this as a date but the better option is to add another object. So here just say timestamps will be equal to true. Okay. Okay, so MongoDB by default will give you will give you the created ad and updated ad
            • 62:00 - 62:30 fields if you add this timestamps of true and I would highly recommend you to add this option in your schemas. Okay, now that we have the schema, we can create the model based off of this schema. So I'll say con node. Again, it should be capitalized and um singular, right? Let's say mongus domodel call this as node and just take a look at the schema that we have. Then
            • 62:30 - 63:00 we'll say export default this model. So what this says basically create a node model based off of this schema. So every single node will have a title, it'll have a content and then it'll add the time stamp whenever they create it. So we'll be using this uh we'll be using this node in other files to be able to interact with the nodes where we can create one update one delete so on and so forth.
            • 63:00 - 63:30 Okay. So just go ahead save this file and we should be good to go and we should be good to go and I have just updated these comments so that you can have it in the source code. All right. So that's going to be it for this section where we have created a database connect to it and then we have created our model right and finally we also learned about the env package where we can access our environment variables so that we can keep our secrets separately from our codebase. Okay, so that's going
            • 63:30 - 64:00 to be it for this section. In the next one we can get started with our actual controllers. They are currently just hardcoded. they are a test. We would like to obviously um communicate with our database where we can fetch them, create create them, update and delete. Okay, so with this in mind, I'll see you in the next section. All right, so this is where we left in the last section. We have connected to our database. Now we'll get started with the controllers that we have. So this is the very first
            • 64:00 - 64:30 one where we would like to get every single node. Currently, we don't really have anything in the database. So this should return something like an empty array, right? So let's first get started with the code and just see how we can create this controller. So first I will mark this async because we'll have some promises. So let's delete this part. I'll say try and catch block. Now in the try we can just fetch every single node. I'll say const not nodes and let's say await import the node model that we
            • 64:30 - 65:00 have. Let's import it. Say chrome. Just go under the maybe just above under the models and get this node.js. Once again, make sure to include the extension at the end. Now, we will say node.find, which is going to give you every single node. If you wanted to fetch some specific ones, you can add this filter, but we basically want to get every single one of them. And then
            • 65:00 - 65:30 let's say as the response we can send the status code of 200 and we can say JSON just send the notes in the catch that means the server failed right if we hit the catch block we can say rans status of 500 this is something that we have talked in the past and we'll just say JSON for the message we can say something like internal server error and For debugging
            • 65:30 - 66:00 purposes, you can put the error in the console. So I'll say console. Let's say error and get all nodes method or let's say controller and then just put the error itself. Okay, let's try to test this out. Now we can send a get request from our browser, right? You can visit SL API/nodes. Just send the request. We got
            • 66:00 - 66:30 a response of an empty array, right? And we can use something else in a desktop application called Postman, which is completely free to get started with. This is what I have. So I have I have already installed it. I'll just go ahead get this. Okay. So it will start the application. Now thanks to this application we can send put request, post request, so on and so forth. Right?
            • 66:30 - 67:00 So these are the things that I have done in the past. Let's create something new. Let's say send an HTTP request to our endpoint. Now we can copy our URL. Let's go right here. It'll be a get request and then send the request. We got an empty array. Now let's try to break something in our code. So here I'll just say find I don't know like find x which is a method that we don't
            • 67:00 - 67:30 have. Is our application crashed? No it didn't. Um let's try to send the request. Okay as you can tell we got the message internal server error. The status code is equal to 500. Okay so this is how that work. Let me try to zoom in and I'll just maximize the screen. So that was the very first thing that we have built, the very first controller. The next one, the other one that I'd like to create is going to be this one. So let's go ahead delete the
            • 67:30 - 68:00 content and get started with it. And I'd like to mark all of these as async. Let's say async function. Now before we write any code, let's think about it. If user wants to create a note, they need to send a title as well as a content, right? Let's pretty quickly see this in action. So right here under the create page, if they want to create a note, they need to pass the title as well as the content. So how do we get these values from the user? So we'll go under
            • 68:00 - 68:30 the VS code. Let's first get the try catch block. So let's say we would like to grab the title which all the structure. Let's say title and content. This is going to be coming from request.body. But if you try to say console log the title and the body by default this would be undefined. So to be able to use this and this should be content by the way. Okay. So by default you cannot access this value. If you want to access
            • 68:30 - 69:00 them you need to head over to server.js and just before your routes you would say app do use express.json which is a middleware that we add. So let's say middleware. Now we'll talk about the middleware in detail. For now just know that this is something needed. Let's try to use it and then I'll explain this on a diagram. I promise. Okay. So just make sure to add it before the before your routes.
            • 69:00 - 69:30 Now let's try to get these values where we would like to create a node. I'll say con let's say new node. And this is going to be our new node. We'll call the model where we would like to add the title. Let's say it'll be equal to this. And then the content will be equal to the content that user passes. Since the key and value is the same thing, we can shorten this. And then let's try to save it to
            • 69:30 - 70:00 the database. So we just created it. We'll say await new node. And then we can send the response. Let's say status is going to be equal to 201. Again, this is something that we have talked about previously. The response could be let's say I'll just add the message for now. Let's say not created successfully. And for the catch block, I'll do the exact same thing. So, I'll
            • 70:00 - 70:30 copy paste. Let's say error in create node controller. Okay, let's try to see this in action. We would like to send a post request, right? If you take a look at it, it is the post request. So, let's go under the postman. We'll say post. Now, we would like to send somebody. Let's select this and just say it'll be row then JSON. Okay. So, just try to type this out with me. We'll have the title. Let's say my first note.
            • 70:30 - 71:00 [Music] And then for the content I'll say some content. Okay, let's try to send the request note created successfully. We got the status code. Let's take a look at the database if this is the case. Right, let's just double check. Okay, so we got the database name which is the nodes DB. Then we got the collection
            • 71:00 - 71:30 where we have our very first document. And as you can tell the MongoDB has added these timestamps by default and it also adds an underscore ID field by default right so you don't really need to add an ID by yourself and I have said in the past that I'll show you this nodes DB now this is coming from uh like it is coming from right here right I said this would be your database name if you don't put anything here this
            • 71:30 - 72:00 would be called as test. Okay, so just keep this in mind. So now that we have created a node, if we send a request to here, and by the way, let's fix this. We should be able to get all the nodes that we have. So I'll go here, send the get request. Okay, so we just have only one node. This is the response that we got. Now let's try to create another note. So here I'll just go into this one. Let's say my second note. and let's say some
            • 72:00 - 72:30 content 1 2 3 instead of getting this message we can maybe show the created node so for this I'll go into VS code okay so instead of sending this message first I'll say this is going to be called as node let's say nodes save which is going to give us let's say the saved node and we can return this as the response so I just say return the saved note okay so this is something optional
            • 72:30 - 73:00 but I think now this should be a little bit more clean let's say my third node and add some content okay so this is what we got instead of that message we actually see the created node now how do I update a node so let's say I want to update this one where I'd like to update the content so I would create a put request um here what it says Sign up to save your
            • 73:00 - 73:30 work remotely. We don't really want to do it. Let's say I'll get this as the put request. So instead of this content, let's say I'll have the updated content and I'll just leave the title as it is. So I can delete that. Now if I want to update this one, I need to get the ID and put it into the URL. Right? So API nodes and this is the one that I'd like to update. And this is how we set that up. Here we can see we are expecting a put
            • 73:30 - 74:00 request to this um like API nodes slash whatever the id is and then we will run this method. So let's try to build it. I'll say try and catch block where we would like to get the title as well as the content from the request.body. So I'll say request body. This will give us some data which is going to be title as well as the content and then we'll say await let's say note do find by id and
            • 74:00 - 74:30 update. Now we need to pass the ID here we can tell it says the very first thing that you need to pass will be the ID. But how do we get the ID from the URL right? How do we know this is the ID that user sends us? So we can say something like request.pr pram id. So we call this as id because this is what we called it here. If you said hello, then you should say request.prams dot hello.
            • 74:30 - 75:00 Right? So these names should match. Now that we have this in mind, the first thing that we need to pass is the ID so that we know which node that we are updating and then the fields that we would like to update. So we'll say update the title as well as the content. So I'll say title just pass this and pass the content itself. Now let's say res.json JSON once this is done completely I mean successfully we can
            • 75:00 - 75:30 say res status let's say 200 it is success and for the JSON we can say message note updated successfully and in the catch I'll go ahead copy this paste it let's say error in update node controller okay let's try to save and give it a go I'll go ahead it add this put method. Now, we didn't really pass
            • 75:30 - 76:00 the title. Let's see what'll happen. Or maybe first, let's try to add the title. I'll not change the title. Let's add a comma right here. Sent the request. Not updated successfully. Let's take a look at the database. Uh I'll just try to refresh. Let me zoom out. So, we got three different documents and the third one has been updated. This is the content that we have. Now what happens if user puts an ID that does not exist. So in this case
            • 76:00 - 76:30 let's try to handle it here just before just before we send the response here. I'll say const updated node. Now I'll say if updated node is not found right let's say updated node if this is equal to a falsy value. We would like to say return out of this function with the status code of 404 which means not found and then I'll say JSON we can send a
            • 76:30 - 77:00 message such as note not found and there is one more thing once you update something at the end you would like to add this option called new equal to true now this is optional but let's save and if you hover over this just read it out loud you will understand what that does basically I'll try to summarize it once you add this it'll give you the new node with the updated fields I hope that makes sense and then now let's try to
            • 77:00 - 77:30 save and send the request with an invalid ID so this is the previous one let's put 45 which is something that we don't have in the database okay not found we got 404 nothing has been updated in the database let's bring us back. Let's say updated content 1 2 3. Since we have the node, we can uh we can update it successfully. And instead of returning this message, I will send the
            • 77:30 - 78:00 updated node in the response. Okay. So I'll try to update it once again to this content. Okay. So this is the response that we got. Now you might be asking, do I have to add the title as well as the content? So let's try to delete one of them. So I just deleted the title. I'll say updated content 1 2 3. Sent the request. Now as you can tell title has not changed. This is what we had
            • 78:00 - 78:30 previously. Let's try to refresh the database and take a look at the title as well as the content. So it'll only update what you have passed. In this case, we only pass the content. So, it has been updated only. Okay. Then we are going to add the very last controller where we can delete it. So maybe you can pause the video and try to build it by yourself. It'll be similar to this one that we have built.
            • 78:30 - 79:00 For the method, we have something like find by ID and delete. Okay? So just pause the video and try to do so. Then we can watch my solution. So I will say a rate node.ind find by ID and delete. How do we know which note we would like to delete? Where we can get well, we can get the ID from the URL. So here I'll say request.pams do ID and then this would give us the deleted node. Let's say
            • 79:00 - 79:30 deleted node. We can check for it just like what we have done here. I'll say if there is not deleted node that means node not found. user put an invalid ID, we can return this response. But else we can say razd.json. You can either like you can either return this one or a message such as note deleted
            • 79:30 - 80:00 successfully. And if you don't send a status by default it'll be 200. So let's try to see this in action. In the catch, we can copy and paste this one. It's pretty classic. We'll just say error and delete node controller. Okay. So, let's try to delete the third node. I'll get the ID. Send the delete request. We don't really need we don't really need to send a body. I'll say none. Send the request. It has been deleted
            • 80:00 - 80:30 successfully. And here we can see we got the 200 by default even if we didn't pass it. But I think it's it's fine to just put this explicitly, right? So I'll just put it as a 200 right here in my code just to be consistent. Okay, so I just saved the file and we have built every single controller that we would need. But I'd like to add one more where we can just fetch a specific node. So we have a get method where we can get all
            • 80:30 - 81:00 the nodes. But here I'll duplicate this and I'll add the ID. Let's say user wants to fetch a specific node. So here I'll say get node by ID. Let's try to create this controller. I'll copy the name right after this one. We can say export async function. Put the name where we can get the request and response. And here let's try to import
            • 81:00 - 81:30 it. Okay, now let's try to build it. It'll be really simple as well. All we want to do just get the ID from the URL and fetch that node specifically. So here I'll say const node await note.ind by id which is going to be this one. And then we'll say if we don't have the note we can return resa status of
            • 81:30 - 82:00 404. I'll say JSON is going to be equal to message of node not found. But in the else case we can say rans.json just return the node itself. In the catch it'll be classic. Now there is even a better way of handling the catch blocks. So you don't really put the try and catch. Instead you would create some kind of a wrapper function but it's a little bit more
            • 82:00 - 82:30 advanced. So I'll just skip that in this tutorial. Okay. So for now it's completely use it's completely fine to use these try and catch blocks. There is nothing wrong with it. I'll put this console. And let's try to see this in action. Let's say I'll get every single node. But now let's say I want to get my first node specifically. I'll copy this ID. Let's create a get method. Um here maybe I'll just update my
            • 82:30 - 83:00 URL. Okay. So instead of getting every single one of them, I'll get this one specifically. Here we go. We only have this as the response. Now normally we can end the section right here. But there is one more thing that I'd like to mention. So when we send the request where we get every single node we can sort this right. So first we get the first one and then the second one. But how can we reverse it so that we can see the latest one at the at the beginning. So we can go under the controller once
            • 83:00 - 83:30 we say just find all of them right after this we can say dots sort and then sort them depending on the create that field. So I'll say created let's try to type this out correctly. Create created and I'll say minus one which means show the newest first. Okay by default I think it is one but let's try to go with minus one. So
            • 83:30 - 84:00 previously we got the first one and then the second one. Okay so again we got the same thing. Let's say one. What are we going to get? Oops. Okay. Why did do I have a typo? Okay. It should be created at let's put minus one. Sorry, my bad. So that's why it did not work. This is what we got by default. But if we have minus one, we should get the second one at the beginning and then the first one. Okay,
            • 84:00 - 84:30 by default it is one. Let's try to see. Okay. So this is something to keep in mind. I'll be using minus one so that in the end result when we create a new node I'd like to see this at the beginning. Right? So this is the latest one created and this is the first one that has been created. If you wanted to you can change the behavior but this is what I'll have in my implementation. Okay. So I have
            • 84:30 - 85:00 also updated this comment so that you can have it in the source code. Now one more thing if you are not using a variable just like this one this is the argument dear request uh we declared it but the value is never read so what you can do is skip them by adding an underscore this is one of the conventions that we have so this is something that you can keep in mind okay so I think that's kind of for the entire section where we have built every single controller that we would need now in the
            • 85:00 - 85:30 server.js JS we talked about the middleares and I said we'll get into the details but that will be in the next section so for now just know that we have added this middleware which is a function basically it allows us to get access to the request body let me find it okay so it allows us to get access these values that we send as a JSON right so when we send the post request
            • 85:30 - 86:00 we have added these fields by default you cannot access them they will give you undefined but just because we have added before our before our routes we are able to use these values okay so I hope that makes sense that's going to be for this section I'll see you in the next one all right so this is where we left now in this section we'll talk about the middleware as well as the rate limiting now these are the concepts that sounds really complicated and confusing for beginners but I'll try to
            • 86:00 - 86:30 simplify it as much as possible. So hopefully at the end of this video you will have no questions about these terms and concepts. Okay, so let's get started with the middleware. I have some notes that we can take a look at. Now the middleware name sounds really complicated and horrendous but let's see what that is. Now basically it is just a function that runs in the middle between the request and response. So what does that mean? So you can send a request
            • 86:30 - 87:00 from the client, right? And you will get a response back from the server. Just before you send the response, you can do something in the middle, right? And this is where the middleware comes into play. Just before you send the response, you can do something. And let's do something really, really simple. So let's say we send a request. Just before we send the response back, we can put a console block in the terminal, right? So let's try to do so. Okay. So right here just before the nodes route I'll go ahead say
            • 87:00 - 87:30 app dot use and you would use this use method to be able to add a middleware. Right? So I'll go ahead say we'll get the callback function. Now just like previously we will get access to request response and also what we call the next function. Okay. So let's try to see it. I'll say console log. We just got a new request. Okay. So once we console log it, we can call the next function. Now
            • 87:30 - 88:00 what does that mean? Let's say we sent a request to this endpoint. Now this function would run, right? Get all nodes because we are trying to get every single node. Okay. So we will first put the console log and then call the next function which is this one. I hope that makes sense. Just pause the video. Try to think about it. It should make sense. Now, let's open up the terminal and try to send a request. I'll send the request
            • 88:00 - 88:30 just before we send the response. We should be able to see this in the terminal. Here we go. And then we will send the response within this function. Right now, you can even add more let's say more meaningful things. I'll put back text. Let's say request method is and let's put the request method and let's say request URL is in the exact same way I'll say
            • 88:30 - 89:00 request URL let's do it once again send the request and in the terminal method was get and URL is / API/notes so this is how easy to understand the middle Now if you think about it, this is exactly what we have just explained just before you send a response back here. This one says go ahead and get access to
            • 89:00 - 89:30 request.body right? So you can get these fields just because you have added this middle layer. If you delete this and send a request, this would be equal to undefined. You can console log it but uh I'll just skip that. Okay. So I think we just understand the middleware what that does. I'll put a comment. Let's say this middleware will parse the JSON bodies. Basically it'll allow you to get access
            • 89:30 - 90:00 to request body. And then this is our simple let's say our simple custom middleware. If you wanted to you can delete it from the code. I'll just go ahead and comment this and leave it in the source code. Now let me go back to my diagrams and talk about some use cases for the middleware. So one of the most popular use case would be the authentication check. So I'll say oath
            • 90:00 - 90:30 check. So let's say you sent a request. Let's say you are on let's say you are on Instagram. You send a request to create a post. But if you are not authenticated server will check it with the middleware function right just before it sends you a response it'll check if this user is authenticated if if user is authenticated they can create the post but if not they cannot right so this is a perfect use case for the middleware or let's say the rate limiting this is something that we'll
            • 90:30 - 91:00 talk about and let's do it immediately now so again it sounds really complicated but it's actually pretty simple a pretty simple concept to understand and I think it's really really important for a junior to understand it in the first place. So I have an explanation let's read it out loud and then we'll see some examples. So rate limiting is a way to control how often someone can do something on a website or on an application like how many times they can refresh a page, make
            • 91:00 - 91:30 a request to an API or try to login. Now what does that mean? Let's say you're a malicious user, right? And non-stop you would send a request to this / API/notes. Okay. So let's say we are trying to abuse this API. Imagine I am just sending get request non-stop and at some point like this server might crash right it cannot handle it cannot handle this overload and imagine we are doing this
            • 91:30 - 92:00 like 10 friends right? At some point the application will crash. Even if it doesn't crash like we are just overloading their servers. So what we can do to block this we can add the rate limiting. So we will do something like you can only send 100 requests per user every 15 minutes. Right? Instead of sending infinite amount of requests, we'll add a rate limiter before like before the API right in front of it. This will be the middleware that we'll
            • 92:00 - 92:30 have and if they exceed this limit we will say you just red limited you have sent too many requests. Okay so I think we have already talked about this but the status code is 429 which means too many requests and rate limiting helps with preventing abuse and protecting servers from getting overwhelmed. Okay, so I hope everything makes sense. So this is the concept that you should
            • 92:30 - 93:00 understand. Now let's try to understand how can we implement this. So for this we'll be using upst. So I already have an account. It's completely free to get started with. So they have a free plan that is really really generous. Okay let's try to log in. They have bunch of different services. By the way we'll be using the reddus with rate limiting. And to put it simple, Reddus is the key value store which will act like a storage. So for
            • 93:00 - 93:30 now just think it like a database which actually is it's like a NoSQL database but instead of collections it is not like MongoDB. We have key value pairs. So we'll see this in action. Just go ahead and log in. I have already logged in. So let's create a database. For the name, we can say think board because why not? The primary region will be the closest one to me. We can select any any of these. I'll go with this one and I'll
            • 93:30 - 94:00 just leave everything as it is. Okay. So, let's say next free plan, right? We don't really need to pay anything to get started with. This will create a database for us. Now, we would like to connect from our Node.js application, right? and they have these documentation like the SDK. So we'll be using in this way. First let's get our environment variables. So I'll copy this. The name
            • 94:00 - 94:30 will be up radius rest url. Let's first copy it. Go under the env file. And then we would like to get the value. So just go ahead copy that. paste this in and then get the token. I think I first should get the key. Okay, come on. That was the I think value. I'd like to copy this
            • 94:30 - 95:00 name. Okay, so I just got the keys and values for my environment variables. So let's save this file. To be able to implement rate limiting, we need to install a package. I'll go under the back end, clear my terminal, and get these packages. So, I'll say mpm install, let's say at up stash slash rate limit. And let's use a specific version. I'll say 2.0.5. And we would like to install
            • 95:00 - 95:30 upstreddis at 1 uh 34.9. Okay. So we'll be using them just in a second. It's been installed. Let's go and run the app. I'll go under the config. We would like to configure the upst. So I'll say upstach.js. It'll be only 10 lines of code. So let's get the uh the imports. I'll say import the rate limit. And this
            • 95:30 - 96:00 is coming from the documentation by the way. You can double check that. Let's say import this from up stash rate limit. And I'll duplicate this. We'll get something from the radius which is going to be equal to radius. Okay. Now let's go ahead type this out. I'll say create a rate limit object. So let's say new rate limit and it is really really simple. All we have to do pass the radius where we would like to
            • 96:00 - 96:30 read it from the environment variables. So I'll say radius uh dot from environment and then the limiter. Now what do you want to happen? Right in my case I'll just put a comment. I'll say I want to create a rate limiter. Let's type this out. That allows 10 requests per let's say 20 seconds. Okay, so this is really low but this is just for testing purposes. Let's say I want
            • 96:30 - 97:00 to allow like I want to have 10 requests per 20 seconds. So this is how we can uh implement that. I'll say rate limit. We can use the sliding window and I'll say 10 requests in third 20 seconds. Okay, 20 space and then s which stands for seconds. And then we can say export default this rate limit. Now to be able to access environment variables, we need
            • 97:00 - 97:30 to import the MV. I'll say importv from this package. So import the package and then call the config method. So we have created an instance and we are exporting it. Now it is time to use it. So again let's use some best practices where we would like to create the middleware folder. This is the folder that we can add our custom middleares. Right? So the one that I'd like to create will be rate limiter.js
            • 97:30 - 98:00 file. So here in this file we will create a function. Let's say con rate limiter and I would like to capitalize this one. Let's say it'll be an async function where we will get the request. Oops. Let's say request get the response as well as the next because since this is a middleware we will do some checks right once it is done we'll call the next function just like what we have done in the past. So let's try to
            • 98:00 - 98:30 say just export it first. Okay. So let's say this will be an arrow function. By the way, just before we send a response back, we can call our middleware. So here I'll say app do use this middleware that we have. Just make sure that you have imported. Okay. So this will check for the rate limiting if user can send requests or should we return an error response. So here let's
            • 98:30 - 99:00 try to implement that. First I'll get the rate limit that we have created under the config upstach.js file. So we'll be using this first. Let's say try and catch in the catch or let's get started with the try. Why did we skip to the catch? So first we can get the success case, right? I'll say const is this done successfully or not? say await rate limit dot limit. Now you would put
            • 99:00 - 99:30 the identifier. Now this would normally like this can be the user ID but in our case we don't really have authentication. So we can put a string like my limit key. So I'll explain this in a second. For now let's say if it is not success right if we got an error then we can say return res. status of
            • 99:30 - 100:00 429 which means too many requests let's say.json JSON and we can send the message say too many requests please try again later but if this is not the case if they have not been rate limited we would like to just call the next function right that means the application will run as expected but if we have some other errors that is related to I don't know maybe upstall.log
            • 100:00 - 100:30 log let's say rate limit error and put the error then we can call the next function as well we can even add the error within that okay so let's save and try to give it a go I'd like to even decrement this under the rate limit so let's say we only uh we only allow 10 requests in 10 seconds right or let's just say event
            • 100:30 - 101:00 Five. I'll go ahead and spam this. So I'll say 1 2 3 4 5 6. Okay. Once we hit that rate limit, we will get this status code and then the message. So we cannot send requests. So you can take a look at the database. Go under the data browser. So here we can see we got five requests and it has time to live. Now we
            • 101:00 - 101:30 just put it as 10 seconds. Let's put it like 60 seconds and try to do it once again. I'll say 1 2 3 4 5. Now the sixth request is going to fail because we sent too many requests. And if you take a look at this, let's refresh. So we have five requests. We have sent five requests and it has still one uh like one minute until this has been until this is completed. So this is
            • 101:30 - 102:00 how easy it is to implement rate limiting with upstach. Now I'd like to change these values. I'll say 10 to 20 seconds. Okay. So that was just testing purposes. And this is still like two let's say it is too less. Let's try to increment that. I'll say maybe 100 requests in every one minute and I have also updated the comment. Now if you take a look at this key it is called as
            • 102:00 - 102:30 my limit key and like you should be able to see it right here right now. Normally as I said if you have authentication in your application you would put the user ID. So you would say rate limit the user with their user ID. So with this every user will be rate limited specifically. So if if I send 100 requests and get rate limited you should not be rate limited right it is done per user right
            • 102:30 - 103:00 if John gets rate limited it should not affect Jane but unfortunately we cannot implement it in this way because we don't really have authentication so we cannot get access to user ID another way of doing it you would add rate limit depending on the IP address um the implement impmentation would change a little bit but for now I'd like to keep it simple I'd like to keep it simple give you the idea and go with this implementation I'll say my rate
            • 103:00 - 103:30 limit okay so with this implementation if if a user sends 100 requests per minute everyone would be blocked right in total once we hit 100 requests per minute uh our application will break so once again most of the time you would like to put this an identifier like user ID or IP address. In this case, we will keep it simple. My goal is to teach you the rate limiting concept and how to
            • 103:30 - 104:00 implement it. All you have to do just write 20 lines of code for the rate limiting and then create an instance with 10 lines of code. So, that's all you need to do to implement rate limiting and then just add it before your routes. Right, we have this comment. I'm not really sure if I should delete that or not, but I'll just leave it right here. Okay, so that's going to be it for this entire section. Now, I'd like to talk about something else just before we end this section. Now, here we
            • 104:00 - 104:30 are calling the connect DB method. And before it connects to the database, we are starting our application, right? So here we can see I'll just kill the back end. Run this again. First application starts and then we are connecting to database which is something I wouldn't really recommend that much. So I think the better way would be first connect to database and then start listening. So how can we do it? I'll cut this. Let's say I'll just put it right here. Let's
            • 104:30 - 105:00 say connect DB. Once we connect it we can say then go ahead run this function where we can wrap it with this function right so once database connected only then go ahead listen let's see so MongoDB connected and then we are started and then we are starting to listen on this port now this is a tiny detail in most of the tutorials you might see people do
            • 105:00 - 105:30 this where they just put the connect DB be at the very top. So right here and this would be at the very bottom of this file which is completely fine for tutorial purposes but I think in production grade applications it should be looking like this. Let me just bring this back. I'll do Ctrl + Z once the database connected and then your application should start because if you think about it if your database uh the connection if it fails what is the point
            • 105:30 - 106:00 of starting the app right? So that's why we say once it is done successfully only then go ahead run the application. So this is a small optimization that I'll just add at the very end of this section. So with that that's going to be it. I think we have built the entire server right the entire API. In the next section we can get started with the front end. So I'll see you in the next section. All right. So let's get started with our front end application. Now I'll go ahead and open up my terminal. I already have the back end up and
            • 106:00 - 106:30 running. So there is no need to delete that. I'll leave it as open. Let's create a new one and cd into the front end. So I'll just press F and then tab. It should be auto completed. Okay. So let's try to create a React application using V. I'll say mpm create at latest and I want to initialize it under the current folder which is front end. So I'll just put dot at the end. Let's go ahead and run this. we will get couple of different
            • 106:30 - 107:00 questions where we would like to go with React and JavaScript. Okay, so we got all the files and folders that we would need. First we need to run mpm install. So this will get all the dependencies that we would need and then we can run the app with mpm rundev. Okay, so let's clear the terminal and say mpm rundev and let's try to visit that. Here
            • 107:00 - 107:30 we go. This is the boilerplate React application that we just got. Okay, so let's first set up the pages. Now, what does that mean? In our application, we'll have three different pages. The homepage, the detail page. So, let's say you click to this one, right? It'll take you to the detail page. And then we have the create page. So to be able to create those, we'll use react router. I'll kill the front end
            • 107:30 - 108:00 and I'll say mpm install react- roer. Now in the past, this was called as react router dom. You can still install it, but in the latest version, it is called react router. And this is the one that we'll be using. So just go ahead and type this out and install it. Now another package that we'll be using for notifications will be react hot toast. So install this one as well. And if you have never used it, I'll try to show you
            • 108:00 - 108:30 that. So let's first say mpm rundev. And let's go under the source under the main first. Let's delete the app.css. We don't really need it. Just delete everything in the index. CSS. delete everything under the app.jsx. Delete everything under the assets. Okay, so first I'll just say rafce which will give me this snippet. If this doesn't work, that means you don't really have this
            • 108:30 - 109:00 extension which is this one. Just go ahead and install it. Once you have done this, you can do RFC. Okay. So let's say this is our app. Now under the main.jsx, JSX. We will wrap our application with the browser router and we will import this from React router. Okay. Now that means in our
            • 109:00 - 109:30 entire application we can use the routing right we just wrapped our entire app with the browser router. Now we can go under the app and create our pages. So first I'll create the pages folder. Let's say we'll have the homepage.jsx and get this boilerplate code for now. Let's try to copy this paste it twice. So we'll have the create page jsx and the content is going to be
            • 109:30 - 110:00 againce and then let's say node detail page. Okay. So this is going to be the content. Now let's go under the app.jsx and try to add these routes. So here I'll delete the content. Let's say we would like to return some routes. Again this is going to be coming from react router. Then we can add our routes. So let's say route imported. Let's say if
            • 110:00 - 110:30 we visit this path which is the homepage. We would like to return this element which is going to be the home page. Let's try to self close this and we can import it. Let's say import [Music] homepage from under the pages from this page from this file. Let's try to duplicate it. If you visit slashcreate, we would like to
            • 110:30 - 111:00 see the create page that we can import. And then finally, we will have the node detail page. Let's paste this in. I'll duplicate this one. Let's say slash node slash some id. This is going to be dynamic. So let's put colon and then id
            • 111:00 - 111:30 would like to return this page. Okay, let's save and give it a go. If you visit the homepage, this is what we're going to get. If you visit slashcreate, we'll get the create page and let's say note and some ID, this is what we are going to get. Okay, so now that we have our pages working correctly, we would like to set up React hot post, which is the notification library that we can use. So this is the kind of output that we're going to get if something done
            • 111:30 - 112:00 successfully or if we have some errors we can show this one right there are a bunch of different variations but we'll mostly be using the success and error cases. So first we need to install the package we already done this. So let's put the toaster in our application. So you can put it under the app.jsx or in this case I'll put it under the main.jsx. Let's try to import it from React hot
            • 112:00 - 112:30 toast. So I'll say import the toaster from React hot toast. And now let's try to add a test button so that we can just test this out. I'll say click me. If we click to it, I'll say on click just go ahead run this function. Let's say toast and import it from react hot toast just like this. I'll say success. Let's say congrats. Okay, let's give it a go. I'll
            • 112:30 - 113:00 go ahead click to it. It works as expected. If you want to get some errors, you can put toast. And this should be the output. All right. So now that this is working as expected, we can go ahead and set up a tailwind. Now, if you have never used tailwind CSS, in my opinion, it is the best way of writing CSS. And this is basically how that work. We have bunch of different CSS classes, the utility classes, and instead of creating them under the CSS file, we just put it
            • 113:00 - 113:30 directly into the JSX. So you would just put it uh directly into the HTML elements. So just like this. So that means we don't really need to create our styles under a CSS file, which is really convenient. So let's go ahead and see how we can get started with it. So, the version 4 just came out and I think it is kind of not stable. It's really buggy. So, what I'd like to do is use the version three. And this is something
            • 113:30 - 114:00 that you'll see all over the internet at the moment. Every single tutorial is still using this one even in my past tutorials. So, uh that's the reason that I'll go with the version three completely uh up to date. It's not outdated like absolutely fine. Okay. Don't don't ever feel this video is outdated. Not at all. So just go ahead select the version three and then under the documentation we would like to get started with the framework guides specifically with V. Okay. So we already
            • 114:00 - 114:30 created a React application. So instead we would like to install the dependencies. So I'll copy this. Go under my terminal under the front end. Let's kill this. I'll just paste this in. So, this will give you the Tailwind config.js file. Let's see. So, we just got this. You would like to delete the entire content and instead get this one from the
            • 114:30 - 115:00 documentation. Paste this in. Save. And finally, you will update the index.css file. So, copy it and you should be good to go. Paste this in. Okay, let's try to test this odd. Um, I'll add first. Let me start the app. I'll say npm rundev. So, I'll add some classes on this button. Let's say class or class name. Text is going to be red 500. Let's say
            • 115:00 - 115:30 padding will be four from all directions. UI should be updated. Here we go. Let's add a background color as well. I'll say bg u I don't know let's say pink of something like 300. Okay. So these are the classes coming from tailwind CSS. Now if you are not able to see this highlight or this auto completion when you type out that means you don't really have this extension called Tailwind
            • 115:30 - 116:00 IntelliSense. So let's see. Okay is this one. Just go ahead and install it. You should be good to go just like what I have. Now we don't really need this button. We would like to delete it. That was just for testing purposes. Okay. So now we got the Tailwind set up as well. The very last thing that I would like to set up is going to be the Daisy UI. Now let's visit daisy.com. So head over to daisy.com. This is the
            • 116:00 - 116:30 Tailwind CSS library that we have. Let's just try to scroll down and see this example. Now to able to get this button, you need to write all these CSS classes without using Daisy UI. But if you use D UI, all you have to do just add a button class. You would get even a better button, right? So this button looks a lot more cleaner than the previous one. But the the thing is you don't really need to type all the classes, right? And another example would be this. So if you
            • 116:30 - 117:00 just use tailwind only, you need to write all these classes to get this output. But if you use daisy UI with it, this is all you have to add some cards, labels, inputs. These are the class names and you would get the exact same output. Okay? And they have bunch of different themes like they have forest, aqua, loafy, pastel, anything that you can check out. In this tutorial, we'll be using the forest. But first, let's go ahead and set this up. Okay, so this is the beauty of Da UI. It'll make
            • 117:00 - 117:30 everything super fast. Now, we'll not be using version five. Once again, this just came out. We would like to use a bit more stable version. Again, this is completely up to date. Nothing is outdated. So, let's say how to use. Instead of getting the latest version, we will get 4.12.24. Okay. So, let's try to type this out. I'll open up my terminal. Let's say mpm install
            • 117:30 - 118:00 dui-d. But here we would like to add 4.12.24. Okay, so it should be installed. Now let's see what is the next step. They say put the import under the tailwind config.js. So I'll go under the tailwind config.js. Under the plugins, we can just say D UI and import it above. So it is the exact same thing as doing
            • 118:00 - 118:30 require, but we are using the import syntax. Okay, I think we should be good to go. Let's try to kill our application and run this again. Now we can get classes from uh the UI. So I'll just say create a button. Let's say click me. And for the class I can use btn and let's say btn outline. Okay, let's try to test this
            • 118:30 - 119:00 out. So here we can see the entire theme has changed. If in your case this is white. If this is a light mode that's completely fine. We are going to fix it. Now this is the outline. We can have btn [Music] primary. So this is how that would look. And basically we have bunch of different components. So we can go under the documentation and under the components we have different buttons. So let's try
            • 119:00 - 119:30 to copy every one of them. Since we are using JSX I'll select this one, copy and paste this in. And this is the output that we got. Right? And again they have bunch of different components that we'll be using in this tutorial. So, they have like built-in really cool components that you don't really need to type anything. Just go ahead, copy and paste. Super easy to get started with and it's really cool for prototyping. All right. So, just
            • 119:30 - 120:00 before we end the section, we would like to use this green theme that we have in the demo application. Right? This is the forest theme that we'll be using. Now, how can you how can you use a theme coming from the UI? So we have this themes section and these are all the themes that they have under the version 4. We would like to use this one. And if you take a look at the documentation, you need to visit Tailwind config and add your theme under the themes. So
            • 120:00 - 120:30 let's try to do it. I'll go under the Tailwind config right after the plugins. I'll say create the Daisy UI. This is the object under the themes. Let's say themes. you would have this array where you would like to put every single theme. Let's say you would like to use the light theme, the dark one, and the forest. Okay? So, if you want to use all of them, you can put it right here. But in this case, I'll be using forest only. So, I'll just leave it right here. If
            • 120:30 - 121:00 you wanted to, you can delete them as well. And then you would visit the let's say app.jsx. Here you would say data dash theme is going to be equal to forest. Let's save and take a look at it. Hopefully it should be working out. Okay. So this this is the theme that we have for forest. Let's say you want to use the coffee theme. Let's go right here. Include that one as well. Now you would say I would like to
            • 121:00 - 121:30 use the coffee theme in my app. So now everything will change to this coffee theme. Right? So this is such a beautiful feature that you get out of the box, right? It's like unbelievable. I'd like to go visit VS Code and as I said, we'll be using the forest theme. If you would like to, you can use anything that you wish, right? You can use something else, but this is what I'll have. So I'll just simplify this array. Okay, so believe it or not, that's going to be it for the entire setup. Let's try to quickly go over it.
            • 121:30 - 122:00 We have built a React application using beat. We have set it up the browser router which is the react router right as well as the react hot toast. We just put them right here and then we created our pages. We have set it up the tailwind as well as a daisy UI. So let's delete them by the way. So we have all of our pages everything working correctly as expected. So in the next section we will get started with the actual features. All right. So let's
            • 122:00 - 122:30 move on with the homepage. This is the output that we are trying to build. So first let's get started with the navbar component where we have the logo on the left and we have this link on the right hand side. Once we click to it, it'll take us to the create page. Now as you can tell in our application, we are using a lot of different icons, right? Such as this one, this one, and that one. For this, we'll be using a package. So let's go ahead and install it. under
            • 122:30 - 123:00 the front end. I'll just kill this. Let's say mpm install lucid- react go ahead and install it. And also I would like to install the axios package so that we can replace our fetch API with the axios. So let's go ahead and install that. I'll explain once we use it. Let's run our app with mpm rundev and get into the homepage.jsx file. So I will create the components folder as
            • 123:00 - 123:30 well. The first component that we'll have will be navbar.jsx. Okay. So let's get started with the homepage. First I'll have the class name. Let's say minimum height will be screened. So this will take the entire screen. The first thing we would like to see will be the navbar component. Let's import it and let's get into it. Now this will not contain any logic at all. It is just UI only. So let's say this will be the header component where we can have the div
            • 123:30 - 124:00 within this. And let's add some classes. I'll say the background will be base 300. We'll add the border bottom. So border-border color is going to be base content. And I'd like to update the opacity. I'll just say 10. Okay. Now let's save. We got this formatting. We'll go into the div. Let's say class name is going to be MX
            • 124:00 - 124:30 auto maximum width of 6x large. Now, if you have never used a tailwind previously, this might look a little bit weird. You might be asking how do you memorize all of them? How do I learn all of them? So, honestly, as you write more and more, you just get comfortable with it, right? And most of the time nowadays, we have AI. You can use AI to create UIs. Uh but most of the time once you just get started with it, once you built a couple of different applications, it it gets really easy to
            • 124:30 - 125:00 write Tailwind CSS because like you learn all these classes, right? You know how to set up a maximum width with all these classes like you have from Xarge until I think 7X, right? Okay. Okay. So all I'm trying to say you just learn these as you build more projects with the Tailwind CSS. Now we can add petting X of four which is around 16 pixels right and then we can add petting Y of
            • 125:00 - 125:30 four as well. If you say petting and four this will add it from all directions right but we only want to add it from X direction and Y direction which means from all directions. So I'll delete this and I'll say padding of four. This is the exact same thing. All right. So after this one, I'll create one more div. Let's say this is going to be flex. Items will be centered and then justify will be between. So we'll have the logo on the left hand side and the
            • 125:30 - 126:00 button on the right hand side. Right? So the justify will be between so that we can have this space between. All right. Now on the left hand side we'll have the H1 which is our logo. Let's say it'll be think board. For the classes, let's say text will be 3x large which is around these values basically. Let's say font bold text will be primary. And then you would put font
            • 126:00 - 126:30 dash mono. Let's say tracking tight. So we have tight tighter or tightest. I hope I pronounce this correctly. So we have tighter. Do we have tightest? I think we don't. These are the ones that we have. And this is used for letter spacing. And this is the value that I'll be using. Let's say it'll be type. Okay. Let's try to see the output.
            • 126:30 - 127:00 This is how that look at the moment. Now let's try to build the right hand side. First I'll have my div. Let's say class name flex item centered and gap of four. So first we would like to have the link uh let's say import the link from react router. When we click to it it should take us to /create and we can add the class name of btn and btn- primary and then we can go ahead add the plus icon
            • 127:00 - 127:30 within this. So let's say plus icon which will be imported from lucid react. Okay. So I just imported that. Now let's say class name is going to be height of five and width of five. Now if height and width is the same value, we can say size of five. It's the exact same thing. And then we can add the span that says new node. Okay. Let's save and
            • 127:30 - 128:00 take a look at the output. This is what we got. Do I have a typo? It should be on the link btn primary, not bnt. Now it should be updated. And once I click it, it'll take me to the create page. So that's going to be for the navbar component. We can go under the homepage and try to build the rest of it. Now in the homepage when we send a lot of requests once we got rate limited
            • 128:00 - 128:30 we would like to see this kind of AUI. So imagine you have rate limited the application will say rate limit reached please just wait a bit and then try once again right so this is the component that we would like to build again it doesn't contain any logic it just has the you know UI elements so let's go ahead and try to build it I will go under the components I'll say rate limited UI jsx and
            • 128:30 - 129:00 here I'll create a state let's say view state. Now let's say by default this is going to be a false and here I'd like to say rate limited and set rate limited. Okay. So basically after the navbar I'll say if we are rate limited and let's even say is rate limited so we can understand this is a
            • 129:00 - 129:30 boolean. Okay. So I'll say if is rate limited just go ahead and return this component. Now once again this component doesn't contain any logic at all. So instead of typing this out I'll go ahead from the source code copy and paste and you can get this code under the components under the rail limited UI.jx.jsx. So just go ahead find this file and copy the entire content paste
            • 129:30 - 130:00 this in. It is a 20 lines of code. No logic at all. Just some markup and tailwind CSS classes. Okay, let's try to save here. I'll say this will be true by default so that we can see it in UI. Okay, so this is the output that we have. Now, please don't get mad just because we copied and pasted. This course is not about tailwind and CSS and these are some really really basic CSS classes. So that's why I'd like to skip this session where we just copy and paste the UI. Okay. Now we'll go under
            • 130:00 - 130:30 the homepage and maybe we can actually try to fetch the notes, right? So I'll create a state. Let's say notes and set notes. By default, this will be an empty array. So let's say use state of an empty array. And then to keep track of the loading state, we can have loading and set loading. Let's say initially it's going to be use state of true because as soon as we
            • 130:30 - 131:00 visit the homepage, we will try to fetch the notes, right? So we can say the loading state is going to be true. And then to be able to fetch that, we can create the use effect. Let's import it and initialize it. So at this point I assume you know the basics of use effect as well as react itself right we have states we have use effects and we have JSX. So that's it. That's all you have to know to be able to follow along. So in the use effect I
            • 131:00 - 131:30 will create a function. Let's say con fetch nodes or get nodes. So this will be an arrow function. At the end of the day we would like to call this function. Now let's try to define the logic. So here I'll first create the try and catch block. Now instead of using the fetch API, this is how you would do it if you would use fetch API. Let's try to do it. I'll say await fetch and then you would put the URL. So let's say
            • 131:30 - 132:00 http localhost it's 501/Inodes. If we send a get request to this uh we can get all the nodes, right? I'll say const data we say await press.json and then we can just say console log the data right let's do it with the fetch and then we will change this code using axis let's say console.log log error fetching notes. Okay, let's try to see this in
            • 132:00 - 132:30 action in the terminal. So I'll open up my terminal. Okay, so first we got the course error. This is nothing related to fetch. This is something a different error that we are going to take a look at. But basically all I am trying to say is that if you were to use fetch, this is how you would do it. But if you were to use Axios, you don't really need to add this step, right? You would say just Axios. Let's try to import it. And then
            • 132:30 - 133:00 we'll say get. This is our get method. If you want to send a post method, you would say axios.post. So on and so forth, right? Now let's try to import it. Okay. Instead of data, you would say res data. So this is a lot more a lot more comfortable than fetch API that's why we'll be using it. Now we have the course error which is something that we need to take a look at. So let's save this file and go over our nodes that we
            • 133:00 - 133:30 have. So course stands for cross origin resource sharing. Now what does that mean? Basically course is a browser security rule. So this has been added by default. That's why we got these errors. Now let's try to see how we can fix it or what is the problem in the first place. So when a website tries to get data from another website like your front end calling an API on a different domain the browser might block it for
            • 133:30 - 134:00 security reasons and this is exactly what happening right this is exactly what is happening at the moment and here's an example let's go over it then we'll fix it. So let's say you have a front end at localhost 3000 and you have an API backend at api.agample.com. So your front end makes a fetch request to get data from this API. So you called it but you got the course error because browser says you're coming from localhost 3000 and you are
            • 134:00 - 134:30 trying to access apiacample.com. That's a different origin. I need to make sure the API allows this. Right. First, you need to make sure that API allows this um this origin, the front end origin. And let's see how we can do it. Right now, I'll go under the back end. So, under the server.js, we would like to add a middleware. Now, first we need to install a package. So, I'll open up a new terminal. Let's say go under the
            • 134:30 - 135:00 back end. I'll say cd back end. And then I'll say mpm install course. So this is the package that we'll be using to be able to get rid of that course error. Okay. So right here I'll just say app dot use. We would like to call the course method the course package. Let's import it. I'll say import course from course. And by the way the version that I'm using is 2.8.5. So when you installed it, you
            • 135:00 - 135:30 could say let's let's just go under the CD back end and say mpm install course at 2.8.5 so that we could have the exact same versions. Okay. Now I'd like to just format this a bit. I'll have the package imports at the top. We'll have the route and all the local imports at the bottom. Okay. Now with this it should be good to go. This basically allows every request
            • 135:30 - 136:00 from every single URL, right? But if you would like to specifically add your front-end URL, you would add this object and you would add the origin. Let's say it'll be HTTP local host and 5173, which is our front end URL. Let's save. I think this should be an array. Um, is it? So, let's leave it as an array. Oops. I think string would also work if
            • 136:00 - 136:30 you have only one value. So I'll just leave it as a string. Now let's go ahead and try to see this in action. Now I'll refresh. Okay. Currently we don't really have any errors that is related to course, right? We have a different error that we'll get into in a second. But basically we don't really have the error that is related to course. If you delete this line, right? Let's just delete this completely. we'll get the course errors. So if you refresh, now we have the
            • 136:30 - 137:00 course policy error. But now we don't really have it. We have something else. I don't know what that is. Let's try to see this in action. Um I think in the backend terminal we should be able to see it. Okay. So it says title is required. Are we missing any fields under the uh under the database? Let's try to see. I don't really know why we encountered this. So we have title
            • 137:00 - 137:30 content title content for every single one of them. Okay. So I think I just found the problem here. I forgot to change this to be get. It should be get method because we are adding post but we are not sending the title or the content. Those fields were required. So here we would like to add the title. Sorry we should add get. What am I doing? Let's save now. It should be working out as expected. Let's try to refresh. Okay. So for a split second, we
            • 137:30 - 138:00 don't have anything. But then we got the console logs where we have these nodes that are coming from the database. So that means we are able to actually call this function successfully. Now instead of just console logging this data, we would like to update the nodes state, right? I'll go ahead and say set nodes that will be equal to response data and then we would like to say rate limited set uh set is rate limited will be false
            • 138:00 - 138:30 because if you are able to get the data that means we are not rate limited and by default let's say this will be false okay but in the catch we are going to check for that state right I'll say just put the console log and then say if error dot response dot status if it is equal to 429 which means rate limited in this case we'll say set rate limited will be
            • 138:30 - 139:00 equal to true but in the else case we can just throw a toast let's say toast error I'll just say failed to load notes let's import the toast function Okay. And then finally I'll say loading state will be equal to
            • 139:00 - 139:30 false. So either we fetched it successfully or we got some errors. In either case finally the loading state will be equal to false. Right now let's try to update our rate limit here. I'll go under here. Let's say we would like to have 10 requests per 20 seconds. This is just for testing purposes so that we can see the UI. So by default we can fetch the notes, right? I'll send couple of different requests. Let's say 1 2 3 4
            • 139:30 - 140:00 5. Now it should break. Okay. So we got 429. But for some reason UI is not updated. Let's see. I'll go right here under the homepage. So I think we didn't hit this if check. First I'll add the question mark and let's say console log the error itself so that we can see the status code. I'll send another request. Let's do it again. 1 2 3 4 5
            • 140:00 - 140:30 and six. Okay. So this is the error. Let's see. So we said error dot response status. So I just paused the video and debugged this a little bit and I have realized that this course configuration should be before the rate limiter. Now why is that? Because we are trying to call I mean we are trying to send a response back but we didn't set up the course. Right. First let's set this up.
            • 140:30 - 141:00 I'll just put it at the very beginning and then we will add these. Now let's go ahead to test this out. I'll send a request. Let's do it a couple of times until we get rate limited. Okay. Now here we can see uh rate limit reached and we got this error under the response. The status is equal to 429 which means too many requests. Right? Okay. So that was something to keep in mind and I'm glad that we encountered this issue so that we just
            • 141:00 - 141:30 understand the uh the order of these middleares are really really important. Okay, now we can go under the homepage and actually display the notes. Right. So, first I'd like to check for the loading state. Right after this check, I'll put a div. Let's say the class name is going to be maximum width of 7x large and then let's say MX will be auto so that the content is centered. Let's say petting will be four and then margin top
            • 141:30 - 142:00 of six. Here I'll say if we are in the loading state just go ahead and render a loading component. For now I'll just keep it simple. I'll have a div. Let's close this off. I'll say loading nodes dot dot dot. Right. And then for the class name I'll say text will be centered. Text will be primary and maybe petting y of 10. So for now let's say it is true so that we
            • 142:00 - 142:30 can see the loading state. Okay, this is what we are going what we are going to see. But once we finish the nodes we'll say nodes.length if it is greater than zero and if we are not rate limited in this case we would like to return this part. We all have a div. Now we'll be using grid. So let me just get a div. So we'll be using grid so that we can have this kind of a this kind of an
            • 142:30 - 143:00 output. We'll have three columns right 1 2 3. And as this screen gets smaller, it'll be let's say two columns and then one column at a time. Right? So let's try to use a grid. In this case, I'll have the class name will be grid grid columns of one. And then medium screens and above grid columns will be two and then larger screens and above grid columns can be
            • 143:00 - 143:30 three. So this is how you can use the bra points in tailwind CSS and I'll say give a gap of six between these items. So here I'll say get the nodes map through it for every single node. Go ahead return a component for now let's just put the div. Let's say have a div. Uh we can just put the node.title title as well as the node dot let's say
            • 143:30 - 144:00 content. Let's take a look at the output. Let's refresh. Okay, so we got the first node. Sorry, first node and then second node. And these are the exact same thing that we have. Now instead of this basic UI, we'll create a separate component. So here I'll delete this part. I'll say for every single node go ahead return a node card component. Let's make react
            • 144:00 - 144:30 happy by passing the unique key. I'll say node underscore id. Then we can pass the node itself as a prop. Okay, let's try to create this under the components. Let's say jsx and import it in this file. Okay. Now we're going to build the UI within this file. So here instead of returning a div, we'll return a link because when we click to the node, right? So once you
            • 144:30 - 145:00 click it, it'll take you to this page. So that's why we need to add the link. I'll say key or we don't really need to add a key here. I'll say the two property. But first, we need to import the link. Okay. So I'll just say first let's grab the note from the props and then I'll make this to be dynamic. I'll say visit the node page slash uh we'll say node
            • 145:00 - 145:30 id and here we are using node because in app.jsx JSX this is what we have called it and then / id right okay then we can add some classes here I'll say class name and instead of typing this out I'll basically paste this in super basic we just added the cart background color hover state some transition and then the border color which is this custom value okay within this link we can have a
            • 145:30 - 146:00 div with the class name of card dashbody. Now we'll go create the H3 that will have the node.title. So this is basically what we are building right this entire thing is the node card. This is the border that we have just added and now it is the title then the content created that date and then these buttons. Okay. So let's try to build it step by step. This H3 will
            • 146:00 - 146:30 take the class name of card dash title text base content and that should be it. Now we'll have the P tag that will be note.content and then I'll just paste the class name right here. So right after this one we'll create a div where we can have that created at as well as the buttons. Right? So I'll say this will be class name of card dasha actions let's say justify
            • 146:30 - 147:00 between and items will be centered margin top of form then I'll have a span that will get the note dot created at date and then class name is going to be text dash small let's say text base content and update the opacity and right after this span I'll have a F let's say class name will be flex item centered and gap is going to be one. Let's make
            • 147:00 - 147:30 sure this is correct. And then I'll have this icon. Let me import it from Lucid React. It is pin square icon. Next to it we'll have the button. Let's put this in. I'll say this button will delete will delete the node itself. Right. For the icon, I'll say it'll be trash to icon. Let's import it from lucid react. And then I'll say class name size of
            • 147:30 - 148:00 four, let's say. Okay. For the button, I'll say class name btn btn ghost and then btn x small. Finally, text will be air so that we can get that uh red color. Okay, let's save and take a look at the output. This is what we got. I think it is working as expected. We will update the background color so that it is like it is highlighted just like in the demo application. And notice how the
            • 148:00 - 148:30 date is formatted right here. But here it's looking disgusting, right? So let's try to fix it. For this we will create a custom function. I'll put it under the front end under the source. Let's create a lib folder and I'll say utils.js. So we'll put a utility function that will basically format the date. So it is around seven lines of code. You can copy it and paste it from the source code or type this out however
            • 148:30 - 149:00 you wish. We'll be using this. Um basically instead of just putting it, we will wrap this with format date function. So I'll paste this in. Let's try to import it. I'll say import format date from let's go one above under the lib under the utils. Hopefully it should be working out. Let's refresh. I think it
            • 149:00 - 149:30 says this is not a function. Do we need to convert this to a date? I'll say new date. Paste this in. Hopefully it should work out. Okay, now we don't really have any errors and it is formatted just like this one. Now, as you can imagine, these actions doesn't really work at the moment. If you click to them, it'll take you to the detail page, right? So, this is the idea of this note. And if you click to this one, it'll take you to
            • 149:30 - 150:00 that page. We will implement the functionalities a bit later in the tutorial. But for now, this should be this should be it for the homepage. Just before we end the section, I'd like to update the background as well as add this effect that we have at the very bottom. I'm not really sure if it is visible, but we'll see this in action right now. So, just head over to app.jsx um under the so under the source code under the app.jsx you will find a div
            • 150:00 - 150:30 that should look like this. I'll go ahead paste this in. Okay. So, just go ahead copy and paste and delete the data theme for now. Let's say class name will be relative. Let's say height full and width full. Okay, let's save and take a look at the output. This is what we got. It's been updated. Background is black. Um, let's say this effect has been added. So, let's refresh. It is working
            • 150:30 - 151:00 as expected. Now, if you try to add the data theme, let's try to paste this in. Let's see what'll happen. Now, as you can tell, we cannot really see the effects, right? Because they have been overwritten with the data theme of forest. So, if you delete this, it should still work out in this case, even though we are not using the data theme. It's because we only have this theme under the themes. So, it understand that it should use the forest theme. I hope that makes sense. So for now that's it
            • 151:00 - 151:30 for the entire homepage where we have a use effect that we fetch the nodes we update our state if we have any errors we will update the rate limiting as well as the UI but else we'll just show the notes okay so let's leave it uh let's leave this section at this point and I'll see you in next one okay so let's build the create page this is the UI that we're going to have at the end of the section where we have the title
            • 151:30 - 152:00 content and then a button where we can submit the form. So let's first build the UI and then we will build the functionality. Okay. So I'll go under the create page file and get started with it. So first I'll create some states. So let's say we will have the title let's say new state. Import that. And by default this could be an empty string. Then we'll have the same thing for content.
            • 152:00 - 152:30 So we are creating these states so that we can keep track of the input that user puts in right and then let's have another state for the loading state right I'll say cost loading let's say set loading by default this is going to be false once they submit the form we will say it'll be equal to true Okay. Now I'll create a function as
            • 152:30 - 153:00 well. Let's say handle submit. Once they submit the form, we would like to run this uh run this function. But first let's build the UI. Okay. So I'll have the div. Let's say class name will be minimum height of screen. Then we can say background base of 200. And then let's go within this div. I'll create another one. Let's say it'll take the class name of container. Let's center this MX auto. I'll say
            • 153:00 - 153:30 horizontally padding will be four but vertically it'll be eight. And then we'll go ahead say one more div. I think we can add the maximum width of 2x large and then MX auto to center it. Then I'll have this link. So it is this one that will take us to the homepage. So let's import it from react router.
            • 153:30 - 154:00 I'll say two to the homepage and then the class name button button ghost and then margin bottom of six. For the content we will put this icon. So let's go here. I'll say arrow left icon. This is something that we would like to import from lucid react. And then I'll say class name size of five. Okay. right after the icon still within the link. I'll say back to
            • 154:00 - 154:30 notes. Okay, let's just see the output. I'll visit the create page. If we click to this, we should be able to visit the create page. Okay, now let's build the rest of it. Right after the link, I'll have a div with the class name of card and let's say background base of 100. Then we'll go ahead create a div with the class name of card dashbody. Within this div I'll have the card title. So let's
            • 154:30 - 155:00 say h2 class name of card dash title. Let's say text of 2x large margin bottom of four. And then let's say create new node. Right after the h2 I'll have a form. Now this will not take any actions but instead it'll take the onsubmit. So once user submits submits this form we will call our method. Let's say handle submit and then we can have
            • 155:00 - 155:30 the let's say the form controls. I'll have a div. Let me scroll. We'll say class form dash control margin bottom of four. So first we'll have the label. Let's say create a label with the class name of label. Now we don't really need the HTML 4. I'll delete that. Let's say this will take the spin label dash text and we can say it'll be title. Okay, let's save. That's
            • 155:30 - 156:00 the very first label that we have. Right after this one, we'll say the input type will be text. Let's say placeholder is going to be node title. And then we'll say class name is going to be input input ordered. Okay. Finally we'll add the value which will be the title state. So that we just bind it and then on change once user types in we'll get that value and update our
            • 156:00 - 156:30 state. So I'll say set title event.target do value. Okay. So that's going to build for the very first input that we have. Right now let's build the next one which is the content. So this will be a text area component that we'll be using. So it's the exact same thing right after this form control. I'll just paste this in. You can pause the video and type this in. We have the form control with the label and then the text area where
            • 156:30 - 157:00 the value will be the content. Right? And we will update that state. So right after this step but still within the form we will create the card actions and let's say justify end so that the button is at the very right hand side right so it is at the end within this row. Okay. Now I'll say the button where the type will be equal to
            • 157:00 - 157:30 submit. Let's say class name will be btn and btn [Music] primary. Now I'll also say that this will be disabled if we are in the loading state. And then let's say if we are loading we can put this part else we'll put this part. So if we're in the loading state, we can say something like creating dot dot dot and then if we are not in the loading state, we'll just say create
            • 157:30 - 158:00 node. Okay, so this is what we have. Let's just say we are in the loading state. I'll say true. So this is disabled now. I cannot click to it. And it says creating. But by default, this will be false. Now we can build the handle submit function. So once we submit the form for now let's say console log the title as well as the
            • 158:00 - 158:30 content. Now if you try to do it in this way once you submit the form it will refresh the page. So let's open up the terminal. I'll put my title and let's say my content. Once I submit it it'll refresh the page. Right? So if you don't want this happen, you would say get the event and first just prevent the default behavior, right? So that it doesn't really refresh the page. So I'll refresh and try to do it once again. Let's say my title and any value can go here.
            • 158:30 - 159:00 Let's submit it. It is not going to refresh the page. So we got these values. Okay. But we don't really want to console log it. Instead, we would like to send a request. So first I'd like to have some validation right I'll say if title is not uh it if it is not provided or let's say if the content is not provided we will throw an error right so I'll say if no title or no
            • 159:00 - 159:30 content then we'll say post let's import it dot error I'll say all fields are required and I'll just return out of this function Now I would like to also trim this so that if they put an empty value still we don't really want to accept it. Okay let's save and give it a go. I'll refresh without any values. If I try to submit it we'll get an error. But
            • 159:30 - 160:00 if they provide some values we can set the loading state to be true and have our try and catch block. And let's even have the finally as well. Finally, we would like to have the set loading state to be false. Now in the try, we will send a request. So let's say cost or we don't really need to get the response, right? So I'll say await. Let's say this will be an async function
            • 160:00 - 160:30 so that we can use await. I'll say axios. Method because we would like to create something and our endpoint. Let's type this out. localhost 5000 N1 / API/notes. Now we would like to send some body, right? I'll add this object where we'll add the title as well as the content. Okay. So once this is done successfully, we can say
            • 160:30 - 161:00 toast.uess not created successfully. And then we can take the user let's say navigate them to the homepage. But how do we do it? So I will get this navigate function and I'll navigate the user to the homepage. So to be able to get this we can say host navigate and we will grab this from the use navigate hook which is coming from
            • 161:00 - 161:30 react router. Okay. In the catch we can just put a post error. They failed to create node. Please try again later or something like that. I'll just leave it as it is and let's console log it. Okay. So, I'll go ahead and save
            • 161:30 - 162:00 this and let's give it a go. I'll say let me just refresh. I'll say learn something and for the content let's say something random. Let's create the node. We have the loading state note created successfully. We are in the homepage and looks like it has been added to the database. So this is what we got. Let's refresh. It is still here. Let's take a look at the database. So previously we had two values. Now we should have three
            • 162:00 - 162:30 documents, right? Okay. So this is the very latest one that has just been added which means everything is working as expected. Now let's try to create another one. But let's say if you didn't have this validation, right? So I'll just delete this and try to create a note without a title or content. So we're going to hit the catch block here. We can see it says fail to create note. And we can open up the terminal. This is the error that we
            • 162:30 - 163:00 have. Let's see what back end returned us. So under the response data, we have the internal server error, right? So we don't really want to return the exact response message back to the client uh because we might leak something, right? But at least user is able to see something failed, right? We at least give them a feedback. So this is perfectly fine to have it. But most of the time you would like to add the
            • 163:00 - 163:30 client validation as well as well so that you so that you can put a meaningful answer. Okay. So that's going to be for the handle submit function. And just like in the homepage if you wanted to you can add the rate limiting uh error case as well. Right? So imagine if they are trying to abuse our API right they are just non-stop sending requests at some point it's going to rate limited so if you wanted to check
            • 163:30 - 164:00 this out you can go under the catch and here I'll say let's delete this for a second I'll say if response sorry if error dot response do status if it is equal to the rate limiting right 429 9. In this case, I'll say return a custom toast. I'll say toast. The message could be something like slow down. You are creating nodes
            • 164:00 - 164:30 too fast. Let's capitalize this. And then if you wanted to, you can update some configurations, right? You can add some options. Let's say the duration is going to be 4 second. So I'll say 4,000 milliseconds, which is equal to 4 seconds. And then we can update the icon. Let's go with this uh school icon, right? Skull icon. But in the else case, I'll just have what we have copied
            • 164:30 - 165:00 a couple of seconds ago. Right? If it is not the right limiting, we'll just put the general error message. And to be able to test out if this is working or not, you can scroll to the top and get rid of this client validation so that we can actually hit the API and get rate limited. So go ahead, comment this out or delete it. Save this file and let's give it a go. So I'd like to just send requests non-stop, right? Let me just refresh the page and go ahead send requests. So we got 1 2 3 4 5 six. I
            • 165:00 - 165:30 think at some point it's going to be rate limited. As you can tell, we cannot really send any more requests. Right? It says sold down. You're creating nodes too fast. Um once it is reseted, we should be able to send the requests. Now we can go back and uncomment this so that it is working as expected. So that's it for the create page. But there is something kind of annoying to me, right? Let's try to see
            • 165:30 - 166:00 what that is. Now if you have realized in every single page or in every single component if we need to send a request every single time we need to type this out right this part is always exactly the same what we can do is to create a global instance and extract it so let's see what do I mean I'll go under the lip I'll create this axiojs file so this is something really common that we'll Okay, this is
            • 166:00 - 166:30 something that you'll see almost in every single large project and you'll be you would like to implement it by yourself as well. So let's say import Axios from Axios package and then we can create an instance. So I'll say Axios instance. Some people call it as Axio instance or API is completely optional. So let's go with API in this case. I'll say Axios.create. and we would like to create an instance. So I'll say open up
            • 166:30 - 167:00 this config where the base URL is equal to http let's say localhost 501 / ai. Now you can also put the nodes but I wouldn't really recommend this for a reason that I'll explain for now just put the API and then go ahead say export default this API and save the file. So now you can go back into the homepage where we are using the axios.get. So
            • 167:00 - 167:30 instead we'll say axios instance and we would like to import it. So delete this and say import oops let's say import axios instance or sorry it was called as API right? We have called this as API. We'll say API.get now we are using this instance that we have created. So that means we don't really need to type this out because it is already under the base URL, right? So we can just say
            • 167:30 - 168:00 slashnotes. Now this has been prefixed with this already. I hope that makes sense. Let's do the exact same thing for the create page. Here I'll go ahead uh let's just type it type this out actually. I'll say API and let's import it. Here this part is already typed out. So we can delete that. Now you might be asking, we already have the notes both here and here. Why don't we include the notes right here under the base URL? So
            • 168:00 - 168:30 you don't really want to do it. It's because let's say tomorrow you will add more features to this application. Let's say you will have an authentication page. This time you will send a request to / API/ users. So you don't really want to uh you don't really want to go back and update this file. So instead let's say tomorrow you will add this new feature. You can just say API.post or delete whatever that is
            • 168:30 - 169:00 slash users. Now this has been prefixed with this one. Right? Let me copy it. Okay. So this is what you have at the moment. So I hope that makes sense. You don't really want to put anything after the API. So at least this is what we would like to do in this case right here in this project. Let's delete this import. We are not using it. Um, okay. So, this is how we this is how we can optimize our code. Make it a
            • 169:00 - 169:30 little bit more organized. Now, we don't really need to type this out every single time whenever we send a request to our API. Okay. So, with this, we can leave this section right here. And I'll see you in the next one. Now, let's add the delete functionality. For this, I'll go under the note card component. Right? This is where we have that button. Okay. So, right here, once we click to this button, we would like to
            • 169:30 - 170:00 delete something. But now, we have some kind of an issue. Let's see what that is. I'll say con handle delete. Uh let's say handle delete. This is the function that's created. Let's say this will be async. Okay. So we'll get the event by default and I'll say when we click this button let's say on click go ahead and call this function.
            • 170:00 - 170:30 So I would like to send the event. Now I'll say call this method where we are calling the handle delete pass the event. This is what this is what you get by default. And then we would like to pass the node id so that we know which node that we are trying to delete. Right? So we'll say node id and let's grab it as the ID. Right? Now in this function we will try to send a request to our API. But the thing is
            • 170:30 - 171:00 let's see if you click to this button it'll immediately take you to the detail page because this entire thing is a link right this entire note card is a link. So what we can do is get the event and prevent the default behavior. So say prevent the sorry event.prevent default so that it doesn't navigate us right. Uh say get rid of the so get rid of the navigation behavior. Let's save and test this out. If I click to the cart, it'll
            • 171:00 - 171:30 take me to this page. But if I click to the icon, right, the delete button, I'll not be navigated because we just prevented that behavior. Okay, now that we have now that we have this, we can just ask for a confirmation. We'll say if not window.confirm. We can say are you sure to delete this node? So this is my message. And if they say no, then we'll just return out of this function without
            • 171:30 - 172:00 doing anything. But if they say yes, we'd like to go ahead and delete that. For now, let's save and see this in action. This is the confirmation that you would get. If you say cancel, nothing would happen. But if you say okay, we would like to run this try and catch block, right? So under the try, let's say import the API. This is something that we have. This is something that we created. Let's say Chrome will go up under the lip
            • 172:00 - 172:30 under the axios, right? We'll say await API. Now, we would like to delete something. So, we'll send a delete method or a delete request. Let's say send a request to slash nodes slash whatever the ID is, right? And we would like to grab this by doing this. And then we can say toast success. I don't know why why my
            • 172:30 - 173:00 VS code does not work the auto completion but let's see. I'll say import toast from react hot toast. I'll say toast error. Um sorry it's success not error because we are in the try block. I'll say note deleted successfully. And in the catch I can just put a console log or I'll just put the toast error. Let's say fail to delete the node and let's put the console lock as
            • 173:00 - 173:30 well. Let's say error in handle delete and put the error message. Okay. So let's save super simple function that we have for the deletion and let's give it a go. I'd like to delete this one. Let's say okay. Now note deleted successfully, right? But UI has not been updated. If you refresh that, it's gone. And if you take a look at the database, it should be gone as
            • 173:30 - 174:00 well. Okay. So, it is not not here. That means it is actually been deleted. But now I want to update the UI as soon as I delete the note. So for this, let's see how we can do it. We have the note card component, right? And this is under the homepage. So we have all of our nodes that are stored in this state. Now once we delete them we would like to update this state and just filter that out. So I will send the set
            • 174:00 - 174:30 nodes under the note card right I'll say set nodes this is the setter function let's go ahead and grab [Music] this and once we delete it successfully we can say update this state right I'll say just get all the previous nodes but just filter out the one that we have deleted so I'll say previous filter which is an array method we can at every single node and just say node doc ID if
            • 174:30 - 175:00 it is not equal to this ID. So this will basically get rid of the deleted one from the array. Right? So let's save and give it a go. I'll delete this one. Let's say okay. UI has been updated immediately. Okay. So I hope that makes sense. Now let's delete this one as well. Now what happens if we don't have anything in the database? So we don't really see
            • 175:00 - 175:30 anything which is fine but I think it would be better if we say something like no nodes found right you don't really have anything just go ahead and create something. So let's try to put that UI. I'll go under the homepage here. We can put that conditional rendering. I'll say if nodes do.length length if it is equal to zero and if we are not rate limited let's say rate is rate limited
            • 175:30 - 176:00 in this case we can return this UI I'll say nodes not bound this is a component that we'll create in a second so let's go under the components and say nodes not found jsx import it from this file. Okay. So now we can build the UI. So this has nothing to do with logic. It's only some CSS classes. That's why I'll just copy and paste. You can grab this from the
            • 176:00 - 176:30 source code. Head over to components into this file. Copy it and paste it. We have one icon, one link, and just some texts. Let's save and test this out. Okay. So this is how the UI will look like. We got the icon, some text and then a button. If you click it, that will take you to the create page. And I think we have just completed this section as well. So we have added the delete functionality right here on
            • 176:30 - 177:00 the note card component. And once we delete once we done this successfully, we would like to update the UI immediately. And to be able to make that work, we have we got this setter method which we sent from the homepage, right? And then we just use the filter method to be able to get rid of the one that has been deleted. Okay, so I hope everything makes sense. Uh in the next section, we can implement the uh the update functionality. So I'll see you
            • 177:00 - 177:30 there. All right. So in this section, let's try to build the detail page. Right. So when you click to one of these nodes or if you click to this update button, you will be redirected to this page where we can fetch the note details such as the title as well as the content. And if you wanted to, we can update them and finally we can delete them if we really wanted to. Okay, so let's get started with it. It'll be under the node detail page. So before we
            • 177:30 - 178:00 build the UI, let's create our states. So I'll have the node let's say set node initially it could be null and we will try to fetch it from the API right and then let's have the loading state let's say set loading let's say use state initially this will be equal to true and then we can have the saving state again I'll say saving set saving
            • 178:00 - 178:30 Okay, let's say use state by default this is going to be false. So when we submit the form we'd like to have some loading state that's that's what we are creating right and then I will get the navigate function from the use navigate um and then one one more thing how do we get the ID from the URL so let's try to visit this page
            • 178:30 - 179:00 uh let's first create something I'll just say my first node and some content. Let's try to submit this. If I click to this, we have a we have an ID in the URL. Now, how do we get this value? So, there is a hook that we can use called use params. And from here, we can dstructure the id. Now, we are calling this as ID because this is what we put. If you had something else like
            • 179:00 - 179:30 idx, then this should be idx, right? Just keep that in mind. Now let's say console log uh let's say this ID open up the terminal refresh the page this is the ID that we are grabbing from the URL okay and if you wrap anything with an object when you are console logging it it'll be formatted in this way so this is something that I almost always
            • 179:30 - 180:00 do it's really convenient like it's really convenient to visualize ize it in the terminal. So instead of saying something like id is here and then put the id just wrap it with curler braces. Okay, now we got this value as well. Let's try to fetch the actual node. I'll create a use effect. So this will be really really simple. This is something that we have done in the past. Whenever the ID changes, we would like to run this use effect, right? So let's say
            • 180:00 - 180:30 I'll have a function called fetch node. Let's say this will be an async function that we would like to call in this use effect. Now let's say we'll have the try and catch block and let's actually add the finally block as well where the loading state will be equal to false. So in the try we will say post response let's say await import the API get method let's say slash nodes slash
            • 180:30 - 181:00 whatever the ID is that is coming from the URL so we'll get the note you can console log it but I'll just set the note state with it I'll say res data in the catch we can just put a toast error I'll say failed to fetch the note let's say if you wanted to you can add this check that we have done in the past so the race limiting check I'll
            • 181:00 - 181:30 just skip that because we have already done this and I'll just add a console log let's say error in fetching note okay now you can console log this let's say console log the note itself. So initially it'll be null. Once it has been fetched, this state will be updated. Right? This is what we got. The content created at title updated at and
            • 181:30 - 182:00 the ID. So this is another field that has been added by MongoDB by default, but you can just ignore this completely. Okay. Now that we got the data, let's try to visualize it in in the UI. And just before we build the UI, I'd like to handle the loading state. So I'll say if you are in the loading state, I'd like to return this part. Let me go ahead paste this in. Basically, we have a div with the loader icon. Let's import it from lucid react. It is taking the
            • 182:00 - 182:30 animates spin class so that it can spin. So for a split second, we are able to see it. Let's just say true. So let's say true so that we can see it in action. Okay. So this is what we're going to get if we are in the loading state. Now let's build the return statement. I'll say return this div where we have the class name of minimum height screen. Then I'll say background base of
            • 182:30 - 183:00 200. Then within this I'll have the container. Let's say it'll take the MX auto and petting X of 4 Y of 8. And then within this div, I'll have one more div that will be the back link. So I'd like to paste this in. It's like link and then the button. Let's import the trash icon, arrow left icon, the link as well. And then let's create this handle delete function. So here I'll just say post
            • 183:00 - 183:30 handle delete. Let's leave it as an empty function for now. Okay. Now let's take a look at the output. This is what we have at the moment. Now this is taking the entire space what I'd like to have there. They are like wrapped. It is a little bit more smaller. Let's try to maybe cut this entire thing or without cutting. We can wrap this with maximum width of 2x large. And let's fix
            • 183:30 - 184:00 this. Then I'll say MX will be auto. Now let's try to wrap this Okay, now UI has been updated. It is taking only this amount of space. Then we can build the card itself. So right after this div. So maybe right after this one. Okay. So just go ahead shrink this still under the maximum width of 2x large. We'll say create the cart
            • 184:00 - 184:30 background base of 100. And let's get into the UI. So this is something that we have done in the past. First let's create the card body. Within the card body, we will have the form control. So I'd like to copy and paste around 10 lines of code. So we have a label and then the input that is type of text. This is the placeholder class name value as well as the own change handler. Right? So that's the very first thing.
            • 184:30 - 185:00 Let's save and take a look at the output. Okay. Now by default we get the value because we say the value will be node.title and when we type something in it'll only update the title. Okay. So I hope that makes sense. Right after this form control just go and give a little bit space and paste this in. We have another form control with the text area and this time it is content. Okay let's save and take a look at the output.
            • 185:00 - 185:30 Okay, this is what we have. Now finally let's put the button. So shrink the form control. Go ahead create the cards actions and let's say justify and let's say we'll have the button with the class name of btn and btn primary. This would be disabled if you are in the loading state or sorry if you are in the saving state right this is the state that we have created for this specifically. And then let's say on
            • 185:30 - 186:00 click we are going to call a function called handle save. Let's try to create it. Um I will duplicate this. Let's say handle save and leave it empty for now. Finally we can put the UI or the text I should say the content here. I'll say if we are saving we would like to say saving dot dot dot but else we'll say save changes. Let's save and take a look at the
            • 186:00 - 186:30 output. Okay, this is what we have. This is the output that we would like to have. Now, first let's handle the delete uh function. So, I'll go right here under the handle delete. This is the exact same thing that we have done in the past. So, first I'll ask for the confirmation. Let me copy and paste. We'll say if user wants to delete it or not, right? Let's just double check that. But if they want to delete it, if they actually want to delete it, we'll go under the try and catch block where we would like to send a delete request.
            • 186:30 - 187:00 Let's say this will be an async function. Import the API. I think we already have it. So we'll just send a delete request to this endpoint. And then if it is done successfully, we can show a toast. And then we can navigate them. Let's say navigate to the homepage. In the catch block, we can put a console log as well as the error toast. So this is something that we have done in the
            • 187:00 - 187:30 past. That's why I didn't type this out. I just like copied and pasteed. Super simple. So for now, everyone understand what this does. Now let's try to test this out. I'll say delete this note. And if I say cancel, nothing would happen. But if I say okay, it's going to be deleted. And now I am in the home screen. Let's create one more thing. Let's say another post. I'd like to create one
            • 187:30 - 188:00 more. Okay. So, let's try to update this one. We'll go into this function. So, first I'll say if there is not node.title title and let's even use the trim method or we'll say if note content is not provided in this case we'll say please
            • 188:00 - 188:30 add a title or content right and then I'll say return out of this function now let's try to do it um here I'll go ahead delete this and this one okay so we need to add at least one of them let's go ahead ahead at this one. So still we are getting an error. Actually we should have both of them because in our model in the note model we said that both of them are required and this is
            • 188:30 - 189:00 exactly what we are checking in the client side. Okay. If we try to save now it should work but we don't have the function. Let's try to complete it. First I'll say set saving will be true. And I'll have the try and catch block. And finally the finally block. I'll say set saving will be equal to false. But in the try we would like to send a
            • 189:00 - 189:30 request. Let's say await api.put request to our endpoint which is let's say slash nodes slash whatever the ID is and then the node that we would like to update. So I'll just pass the node object as the second argument. Now we need to say async so that we can use a wait. Once this is done successfully we can say not updated
            • 189:30 - 190:00 successfully and then under the catch we can handle it properly. Okay. So this is what I just copied and paste it. Let's try to save and give it a go. I'll say another post one, two, three. Right, this is what we have updated. And let's say some content just got updated. Okay, it's been updated. Let's take a look at the homepage. Here we can see the title and then the content. Now, what you can do also once you once you
            • 190:00 - 190:30 have updated successfully, you can navigate them to the homepage. Let's actually do it. and test this out. I'll say one more is also [Music] updated. Once it is updated right here, you're in the home screen. And I think with that we have completed this section as well. Now all of our pages working properly. Now one more quick note if
            • 190:30 - 191:00 you're wondering where do I get this kind of a like pattern that looks like this. So there is a website called bg.ibelik.com. I don't know how you pronounce it but this is the website where they have bunch of different patterns. So you can preview it right like we have this one all these and I think this is the one that I have used. So you can copy the code and I just changed the color as well as the
            • 191:00 - 191:30 height. So this is I think a bit a little bit more longer than what we have, right? So I just change the height as well as the color. You can use different things if you really wanted to. Okay, so this is something that I wanted to mention. And the very last thing that we need to do is to deploy this application which is going to be in the next section. So I'll see you there. All right. So it is time to deploy our application. Now first I have some
            • 191:30 - 192:00 notes. Let's try to see it on the diagram. Now, the first thing we would like to do is to push our code to GitHub. Once our code is live on GitHub, we will use a platform called render.com. They have a free plan, so we don't really need to pay anything to deploy our application. Right? So, we're going to push our code to GitHub and then they will take our code and deploy it on their platform now. If we want to push our code to GitHub, we would like to hide the env file, right? Because we
            • 192:00 - 192:30 don't really want to push those to GitHub. We would like to hide them so that no one can see those credentials. For this, we would like to create a get ignore file. Now, here we already have it. I'd like to take this and put it right here in the root so that it can apply to both of these folders. And then at the very end I'll say uh just ignore the env file as well. So that this file is not pushed to GitHub. Now let's open
            • 192:30 - 193:00 up the terminal and I have killed the back end as well as front end. Now I am under the root which is here. Right. Let's say initialize this as a get rep. Let's say get in it. Okay. So an empty git repository has been initialized. So if you take a look at it, the note modules have been ignored both here and under the back end as well as thev file. So now if we if we push our code to GitHub, we will not see the
            • 193:00 - 193:30 dependencies. Um we will not see the MV file as well as this dependencies, right? And let's actually try to do it maybe. So we can say so I will say get add everything, right? and let's say get commit with the message. Let's say initial commit. Okay. So I'll just push my changes. But this has just been added to the staging area. Now we would like to create an empty folder, an empty
            • 193:30 - 194:00 repository here. Let's just call this as thin port or should I call this something else. So this is the repository name that I'll be going with. Let me just zoom in. For now, it'll be private. Once I publish this video, it'll be public. So, for now, let's say uh private. And I will create it. Now, I'll just go ahead copy this because we already added our commits, right? We committed our changes. And I
            • 194:00 - 194:30 think just a couple of seconds ago, I said it'll be in the staging area, but not really. It's been even committed, right? Okay. So, let's say just paste this in. It'll take everything that we have and push it to this repository. Let's refresh. Okay. Now here we can see under the back end we don't really have note modules and we don't have the env file. And same for same thing for the front end. We don't really have the node modules right here. But now render if
            • 194:30 - 195:00 render.com wants to deploy our app they want to get the note modules right without that our application would not work. So for this we will create a file right here so that they can install our dependencies. So here I'll clear up my terminal under the root I'll say mpm init-y which is going to create a package json file. So within this file we will uh we will manage both the front
            • 195:00 - 195:30 end and back end. So we will deploy both of them from here. So we'll have two different scripts. I know that this might look a little bit complicated for now, but just follow along with me. In like 5 minutes, everything should be clear. So, we'll have a build commit build script where we'd like to install the node modules for back end as well as the front end. So, here I'll say go ahead run npm install first for the back end. So, I'll say run this under the backend
            • 195:30 - 196:00 folder. We can say d-p prefix backend. Once you have done this, go ahead and do the same thing for the front end. Right? So I'll say mpm install uh d-p prefix front end. Okay, let's save. Now I'll go ahead delete these node modules and let's try to run this command. So I will say mpm run build which is going to install the
            • 196:00 - 196:30 dependencies for the back end as well as for the front end. I'll just run that. And now here we can see we got both of these node modules. Okay. So for now let's ignore this warning. And under this build command we would like to add one more thing. So in production you would like to always build your front-end application so that everything that you have here will be optimized and it'll be put under a under a special folder called this. So let's see what
            • 196:30 - 197:00 does that mean. I'll say once you installed all the dependencies just go ahead run this command as well which is mpm run build but run this under the front end. So let's say d-p prefix front end. Now let's save and try to run this command once again. So it'll go ahead install the dependencies and then it'll try to build the front-end application. Now if you can see we have the folder which is the optimized version of the
            • 197:00 - 197:30 React application that we have built. Okay. Now we would like to deploy everything that we have right now. The current state of our application is this one. So we have the React application under this port and our API under this port. Now what I'd like to do just take the entire front end, right? Basically serve this under the same domain. So we don't really want to have two different domains. Even though you can have it,
            • 197:30 - 198:00 right? It is just completely optional. If you wanted to, you can deploy this separately and deploy your back end separately, right? But what I'll be doing is to take everything serve it under a single domain. Right? So let's say if we visit my website.com we are both going to see the react application and we can send request to our API as well. So we'll see what that means. So for now just keep that in mind. This is the deployment
            • 198:00 - 198:30 model that we would like to have. Okay. Now one more thing if we have both of if we have both the client and back end under the same domain that means we can get rid of the course errors right so okay so previously we said that if you have two different domains you need to set up the course but now we'll have only one so we can get rid we can get rid of the course configuration okay let's see how we can do it first I'll go
            • 198:30 - 199:00 under the back And under the server.js file, we'll just write elicit code to to deploy this correctly. Now let's import the path package which is something that is built into node. You don't really need to say npm install path. It is already provided. Okay. So just scroll to the very bottom. Right after your API routes, we will add a configuration. So
            • 199:00 - 199:30 we will use a different middleware that is coming from express. So let's see how that work. I'll say app dot use express static. I'll say let's call this method with the path dot join. Now here we will put a path for the front end folder. Now let's try to create a variable. Let's say const name. This is the convention. We'll say path.resolve call the method. Now if you
            • 199:30 - 200:00 console log this if you say console log their name it'll give you the source uh for the back end right from here we would like to go one up so that we can go under the front end from here we'll go under the this folder okay so let's see how we can type this out I'll say within the path jojoin method just go ahead get the door name now we are under the back end let's go one up and from here we'll go under the front end and Then we'll go under the folder. Now this
            • 200:00 - 200:30 basically says serve our optimized react application like serve this as a static asset. Right? So once again we are under the back end right. So we are here we said go one up. So you are in the root go under the front end and find this this folder make it a static just serve them uh because they are our static assets. And then we'll say if if we got any kind of requests so we'll say
            • 200:30 - 201:00 app.get any route. So if we get a get request any route other than these right anything other than our API nodes you would like to serve our react application. So we're going to run our controller let's say request and response. I'll say rest send file. We'll say path.join join let's say underscore their name again we would like to go one up under
            • 201:00 - 201:30 the front end let's say this time we'll go under the list again but we would like to serve the index html file so under the test this is where your react application will will be started so this is the file that we would like to display let's say index html Okay, but we only want to do this if we are in the production, right? Uh we only want to do this if the application is on
            • 201:30 - 202:00 render.com. So I'll go ahead cut this. I'll say if we are in the production and we can do it with a with an environment variable. I'll say process env env if it is equal to production only then go ahead implement this right and then we can do the same thing for the course as I said this is only needed in development because in
            • 202:00 - 202:30 development we have two different domains in production we will have only one right so we can say if process env dot node dnv if it is equal to let's say if it is not equal to production only then at the course configuration. Okay. So let's try to save this. Now one more thing that we that we need to do now once we build our
            • 202:30 - 203:00 application we would like to start it right. So to be able to start that we will add a start command. This is the command that render will run. So let's say mpm run start. Run this command under the back end. So once you run mpm run start under the back end. It'll go ahead. Let's see. It'll go ahead run this script which is going to start our application. Now let's save and we can test this out
            • 203:00 - 203:30 without even deploying. Um I'll go ahead open up the terminal. Let's clear this up. I'll say mpm run build. This is going to build our application. Install all the dependencies and then we can say mpm. Let me clear this up. I'll say mpm run start. Now this will start our application. So if you visit localhost 501. Now normally we would get our API
            • 203:30 - 204:00 but now we will get both the API and the react application. Looks like we couldn't. Let's see why this is the case. It says 404 not found. Well, of course, this is the error that we will get because we forgot to set up the uh we forgot to set up the node ENV, right? Let's say node env is equal to production. Let's say production and we don't really need codes. So, this is what we'll have in
            • 204:00 - 204:30 the render.com. But when you are developing the application, you would like to mostly say development. But just to test this out, let's say production and I'll kill this. Run this once again. Now we can refresh this page. So under the backend URL, right, we are able to get the React application because it has been served under the server.js. So we said if we are in the production go ahead uh go ahead and you
            • 204:30 - 205:00 know serve the react application which is under the this index.html. Okay. So I hope that makes sense. Now I will explain this once again. Let's try to complete this. Um one more thing that we need to do. We'll go under the front end. I think this is the very last thing under the axios.js. So here we need to update something. So here we say that our base URL is localhost 501 which is absolutely fine in development but when we deploy
            • 205:00 - 205:30 the application we will get a different URL right so I don't know what render will give us but let's say it'll be something like my example web app.com we don't really know what the URL is going to be in production we don't really have something like local host so we will make this to be dynamic so I'll say let's create a base URL. Now we can check for the environment in vit by doing import meta
            • 205:30 - 206:00 env mode. So we'll say if this is equal to development in this case our base URL could be this one. So I'll cut this out. Paste this in. But in production we'll say whatever that is slash API. Right? Okay. So this will make it to be dynamic. And now let's say the base URL is going to be this value. So I have just added a comment just like what I have said in production
            • 206:00 - 206:30 there is nothing called local host. So we have to make this to be dynamic. Okay. So that's everything that we would need. Let me pretty quickly go over this and we will we will push the these changes so that render can deploy it. Okay. So the first thing we have done is to add the package JSON under the root so that we can add the build command. So we need to install the dependencies for the back end as well as the front end. Now why this is the case? Because in GitHub we don't really have we don't
            • 206:30 - 207:00 really have those node modules right. So render cannot see those. So for that reason we will say hey render go ahead and install the dependencies and then just build the front end application so that you can get the optimized version of the react app and once you have done this you can start the app by running this command under the back end and then under the back end under the server.js JS we have added this configuration where we said if we are in the
            • 207:00 - 207:30 production environment go ahead serve the react application as the static assets and then if they visit any route other than APIs other than the API just go ahead uh render the react app so that if we visit localhost 51 instead of getting only API we will get the react app as well okay and then we also get rid of the force configuration in the production because now we have only one domain. Okay, so
            • 207:30 - 208:00 that's it and at the very end we have added the node MV to be production but of course this should be development uh only in production in render.com we will make it to be production. Okay. So let's save and kill our application. Now we can uh let's say commit our changes. Right. I'll say get add all. I'll say get commit-m let's say something like uh prepared for the
            • 208:00 - 208:30 deployment and so this is the entire thing that I have let's just commit this change and I'll say get push so hopefully we should be able to get the latest changes okay just now this is what we got now I'll visit render.com so they have a free plan that you don't really need to pay. Here we can see and I already have an account. So I'll just log in with my GitHub
            • 208:30 - 209:00 account. Okay. So I have already deployed the test version like 1 hour ago but let's try to do it from scratch. So I just did this so that I don't really get any errors and give you the best result. So now let's try to deploy this repository. I'll say deploy a web service which is going to be this one, right? It says 1 minute
            • 209:00 - 209:30 echo. Let's wait for this to load. So just leave everything as it is. But we would like to update the build command. So for this we would like to run this one mpm run build. And then to start the application we'll say npm run start. So the build command is going to be npm run build and the start command will be npm run start. Okay, I'll say use the free plan. We don't really need
            • 209:30 - 210:00 to pay anything. And then I'll go under the environment variables. Let's copy everything that we have right here and then paste paste this in like I'll say just go ahead delete the node EMV. Don't even put the production. It'll understand that it is under the production. So just don't put the node env uh these four different values and then we can just say deploy the web service. Before we do so I would like to talk
            • 210:00 - 210:30 about the free plan. Now since this is the free plan, it'll go inactive after 15 minutes. So let's say you deploy the application but you don't visit it for 15 minutes, it'll go inactive. So for the next time you visit the application, it'll take about 1 minute for that to load. Right? So, just keep that in mind. If you would like to always have this open, maybe you can go with the cheapest plan that is possible, which is $7 per month. But in this case, I'll go with
            • 210:30 - 211:00 the free plan. Let's say deploy the web service. Now, um I think this will take around two to maybe 3 minutes. So, let's wait for this to complete and then I'll just come back to the video. And by the way, here you can see it'll first run the mpm run build. So it runs the mpm run build. It'll get the dependencies. Okay, this is really annoying. It just scrolls down, but it'll get the dependencies for the back end, for the front end, and then it'll build the
            • 211:00 - 211:30 React application and then it'll try to hopefully deploy the app successfully. So it says front end build was successfully done. So let's wait for this to be live. All right. So, looks like MongoDB connected successfully. Server started and our service is live. Let's just put a pretty quick confetti because why not. Okay, now it is live. So, it'll give us a URL. Let's scroll to the top. This is what we have. I'll just click to
            • 211:30 - 212:00 it. Here we go. We got our React application. So, we can create another one. Let's say from the production say it is live successfully. It's been created and we can see it it's on the UI, right? So that means everything works successfully. We can delete it if we really wanted to. We can update one
            • 212:00 - 212:30 let's say something different. Here we can see and it should be completely responsive as well. All right. So that's the entire application. There is one more thing that I'd like to update. Let's visit the upst.js file. Here we have a comment but we have updated the value. It is not really matching with what we have. So let's say
            • 212:30 - 213:00 100 requests per minute. I'll say 60 seconds. You can update this value, but this is what I'll have in the source code. So, I think that's going to be it for the entire application. We have built an entire back end, an entire API as well as a complete React application and then we have connected both of them and we have even deployed the app. So, this was one of the most comprehensive beginnerfriendly tutorial that I have ever made. Seriously, like I could
            • 213:00 - 213:30 record this entire thing in one hour, but I think it's now more than three hours because we just went into the super details. And I'll leave the diagram link in the description. You can take this, you know, just have it as a note. There's a lot of cool information right here in this diagram. So, we have more complex projects with this exact uh with this exact text tag that you can check this out, right? you can check out. Um I'll just add this very last
            • 213:30 - 214:00 commit and then end this tutorial. So let's say get add everything get commit-m uh let's say up stash.js js file updated or I'll say rate limiter updated I'll say get push and one more thing whenever you add more changes new changes render will see that change from your GitHub account right it'll immediately it'll immediately see that
            • 214:00 - 214:30 you have a new change so it'll go ahead and try to deploy it so that you can get the very very latest version right as you can Well, now it is deploying and you can take a look at the logs just to see if it is going to complete uh complete successfully or not. In our case, it is done successfully. So, I hope you enjoyed the entire tutorial. Once again, congratulations for watching this entire tutorial. I hope you enjoyed it. I'll see you in the very next one.