Build a Fullstack Blog App using MERN (mongo, express, react, node)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome back today we are going to build a full stack block application using mynstack so mongodb Express react and node on the home page we are going to fetch all the posts from our database and when we click on a specific post then the information about this post will be fetched alongside with the information about the author so you'll learn how to join information from different database collections using Mongoose and populate function we have also register and login functionality so you will learn how to implement authentication to a man project using Json web tokens on top of it we check that only the author of the post can edit their own posts so here for example I can edit this post because I am the author of this post but I cannot edit for example this one because the author is not me on the post edit page we can change title summary of The Post cover image and then content of the post as you can see for the content we are using Ridge editor which allows us to add headers images lists and so on I can change also the image here to for example this one so as you can see you will learn also how to build this simple upload functionality and you will learn many other things like how to handle course errors how to use react context for storing user information how to use Mongoose and create models how to handle relationships with nosql databases Json web tokens for authentication how to use cookies in a meron project some CSS tips and tricks and much more the whole product is built from scratch so there is no starter cord or anything and I tried to make this tutorial super easy to follow so even if you are a beginner you shouldn't have any problems with completing this product as always all I ask for is that you will smash that like button and if there's anything specific you want me to build next time let me know in the comments and now without further Ado let's dive into the decoder so as always we start with an empty directory here here in my code editor and on the right side I have a Chrome browser open with an empty Tab and here we just have in another tab just some content for our blog uh but we will focus here first on the code and I have only an empty directory open here as you can see there are no files inside this directory and here I will start by creating two directories inside the first one will be client directory oops client for our react app and the second directory will be for our API which will be our Express JS app so let's start with client directory I will open Terminal here and let's see we are inside man blog directory but we want to get inside client so let's start by going inside with CD and client and now let's install our react up here so let's do yarn create react app and the dot so it will be installed here now enter and it will start installing all right so now as you can see it's installed so inside the client we have our react app and API directory is empty for now so inside our client we have source and we have all files for our react app that we can now start with yarn start so let's do this let's do yarn start enter and now our app has opened so let's open app.js and let's close this files for now and let's hide our terminal and let's maybe start by removing all of this and just leave an empty div let's put maybe test here let's also clear this up CSS inside let's just select everything and let's remove it let's go back to MJS and we don't need this logo that's this video so we can remove it as well right so now we see our test here I will make it a little bigger and now let's start by putting some HTML structure to our blog so we want to have some kind of logo and then navigation like login register and create the new article and then underneath we will have the list of all the articles right so um maybe instead of div let's put a main and then element here and then then on the top we want to have a header so let's put header inside header we want to have some kind of logo so let's do maybe a tag with class name logo and it will be while the logo will be let's say it will be just my blog and then after logo we want to have some kind of navigation wavelengths like login and register and nothing that will be it so now let's start Maybe by putting some styles to our header so we have header we have a a tag with class name logo and then we have navigation with two links let's go inside app CSS and let's do some styling so first maybe let's add some padding on the main element like maybe 10 pixels at least so we'll have some padding from the top and the bottom and then I think it would be nice to have a the whole content centered so it will be like this so let's say that the max max width will be I don't know let's say 600 pixels 600 pixels and the margin will be then 0 Auto because it should be centered and now let's see if I make it this big yes it is centered if I zoom out oops here zoom out you can see it's centered right let me make it make it 500 pixels all right now let's go and do some header standing for the header as you remember we have two elements the first is logo and then we have navigation with the links so we can do display Plex so those two will be next to each other and then we can add the space between so justify content space between and then we that's how we have a space between those right and now maybe we can Define how the links in sha inside should look like so let's do a header a tag and there well let's remove the creation so let's do a text decoration none let's make them almost black let's do a color of um has to inherit so those will be those will inherit black color that is default but maybe we can change this black color to make it more grayish so inside the body of the color of let's do free free so now it's not pure black it's saying more grayish and I think that would be good maybe we'll do two to two all right um now for our logo I'd like it to be bold so let's do header a with class name Logo should be font wave of bold yes I think that's more better and now for those links those links are a a tanks inside the header knob sorry to header nav and let's put that this will be also display of flex but we will add some gap of let's say 5 pixels and maybe even more let's do 15. I think that's that's much better all right um now maybe we can add some margin bottom from the header so let's do margin bottom and let's say maybe 50 pixels so we can have some spacing here from the header to the content that will start somewhere here right back to fjs and under our header let's now maybe put some content so um let's maybe put the div with class name entries sorry in trees and then div we have class name entry and this will be a single entry in our blog right um maybe we don't even need this entry so maybe we can start by removing this let's start within a single entry inside single entry we will have an image yes and maybe I will just grab and image from here and we copy the image address and I will put it here and well what else do we want to have we need a title so let's use H2S and for the title I will put maybe something like this Full House battery backup coming later this year and then it will be good to say to have some kind of a brief entry to brief description of the of the post of of this entry maybe we can call it post and maybe we can grab I guess today special event blah blah blah up to this point so I'll add the paragraph here and I'll put this and we'll add this day on the beginning and uh well let's see that should work yeah and we have it we have the image we have some text so uh now let's I will just copy this and I will put it two more times so we'll have three posts with the same images and now let's fix the styling so let's go back to our app CSS that is here and now and first we have this div with class name post and what's wrong first and this image is too big so I think that we can start by going all the way up and let's go and do that all all images should have a Max wave of 100 percent so at the most all images will take all the available all the available space on the width of hundred percent and Max wave defined by our brain element is this so that's why this element is this big all right and the next thing is I would like to have images on the left side and then title and short description under on the right side and to do this I will go back to app.js and let's see we have image here and then we have H2 in paragraph and those two I will put them inside the separative and maybe with some class name like content or maybe texts and now let's put those two inside and now those other two blog posts and we need to fix them as well so we'll remove them for now and I will just re-copy the one that we have just fixed so image inside each post we have an image and then we have a div with texts we have two elements so now inside our app CSS we can do that our div with clapping post is display of typeflex yeah um and now maybe you can change that div post image is much smaller so it's the width of 50 pixels 50 sorry and that's uh that's much better uh let's see if this image is stretched yes I think it is so as they have Auto this didn't help and this is because by default all the children inside the flex all stretched from the top to the bottom so to fix this I will go back and inside the inch post I will put each image that she is on the left side I put it inside the separate div so let's create a div with class name image and I'll put the image inside and now we need to fix this wave under to both so I'll put on the second and on the third as well so now inside the each post we have a div with class name image and the image is inside and then we have the wave class name texts and those two elements are inside the header and the description right and now it is much better let's go back to app CSS and let's see we can remove this with a 50 percent and yeah now now it's uh now it's Barbara I can remove this and now let's see what do we want to do now and we have Dave with inside devpose we have Dev with class name image or was it EMG it was image so the image so this is the left side the left div and maybe we can make it even smaller that's maybe the wave of 40 percent well it shouldn't be that small I think that a better way of fixing this would be to instead of using Flex using grid here because this way we can Define the grid columns so let's do a grid template columns and this way we can Define the first and the second column so let's do that let's say let's start with 50 50. just do one fr1 FR two columns with the same sizing and let's add a gap here so let's do a gap of let's say 20 pixels yes and now to make the First Column smaller I will do 0.8 FR f r and the second will be 1.2 fr maybe we can make it the little bigger let's do 0.9 and 1.1 yes and I think this will work now the next part is we need to fix this header here so they've post and div text H2 and let's remove all the margins to zero yes let's make this a little bit smaller so it's the font size let's do two RAM and let's see that's too big let's do 1.6 Ram oops 1.6 Ram yes I think that's better I will try to zoom out a little bit to see hundred percent yeah um with 100 of you as you can see it's uh it's uh kind of small but that's okay let's make it 1.5 and for desktop let's actually make it wider so I would do 700 pixels here so it will be wider and the logo I want the logo to be bigger so it's the font size of 1.4 Ram yes and maybe even bigger is the 1.5 and now and the problem is that as you can see this logo is not in line with the links the links should be pulled down a little bit so for header let's do align items Center and now they have been pulled down login and returnings right but um back to our posts another thing is I would like to have more spacing between the posts so let's say it will be margin bottom on the post of well at least the 35 pixels I guess and maybe just 30. yeah that's um that's much better we can maybe increase the padding from the top so let's do this and we're on the main element with 10 pixels on each side maybe we can do on the header we can add the margin top here as well the modern top of the 20 pixels yeah so we have some more spacing right let's scroll down here and let's see our headers could be a little bit bigger so let's try with 1.8 yes that looks good now uh one thing I forgot about is we would need to have some kind of more text here between the header and the brief description about the outdoor and the time so let's go back to our app.js and let's see here we have a single post we have texts here and under the header let's add the paragraph maybe with a class name of maybe we have a class name of info and well here let's put some let's see how others do it they put like a bold name and then brighter date so in this info let's put a span wave classroom outer and maybe a link with custom author instead and let's put my name for now and then let's put maybe a Time tag with a date so do 2023 and January and today is six and I think it's 16 45. so we have now here a user author and the date in the first one but we'll fix it in a minute I will put also a class into this brief description of the post let's put the class name here and maybe we can call this one simmer summary of the post right now I will copy this div text and I will update on other two posts so copy and paste and now let's go back to app CSS right and now div dot post and let's see let's fix the outer link and um yeah what was the name of this div it was info paragraph info paragraph info and let's see we have a lot of spacing here that we don't want to to have so let's say I will inspect this element I make this bigger and let's see yeah on this paragraph We want to have no margin so it's the margin zero and now let's change the color to maybe like AAA so it will be much brighter and that is too bright let's do a88 and let's make it smaller so let's do wet font size of 0.7 Ram and let's make it bold won't wave Weebly bold maybe a little bit of margin so I will do 10 pixels from the top and the bottom and zero on the sides maybe that's too big let's do six pixels from the top and the bottom yes um that looks good and then now as you can see we have done we don't have any spacing here so I think we can fix it by doing display of type legs and adding some gap of 5 pixels so now we have some spacing maybe more spacing like 10 pixels yes and now for the outer link let's do the post uh paragraph info and then we have a span sorry a tag with last name outer let's make color of it of black or almost blank so let's do three three yes and that's better now let's fix the text underneath so this summary of the post so let's do a div with class name post because it's inside this post and then let's do just paragraph summary summary of the post and there well let's do margin let's try with zero uh let's do six pixels from the top and the bottom and zero on the sides um that I think that's two tool that's the 10. and that's better but now I would like to have more space in between the lines here so let's do line half of uh let's try with 1.3 Ram yes maybe more let's do 1.5 yes I think this will work less than 1.4 yeah I think this is saying good enough now the next part is I would like to do this login and register page and but the failures we need to fix routing with our react so let's go to our app.js and for now we have an omni home page here but we need uh to add some routing so I will open my terminal and in the new tab let's yarn add here react router Dom and we are going to use serial reactor to them version 6. so let's do this so first maybe as you can see we have three posts with the same content and maybe we can get rid of those two and we can leave only one and we can put it as a separate component so I will cut it from here and I'll create a new component in source so that's the new file and let's call this one a post.js and here let's do just export default function post and it will just return and in parenthesis I will just paste it and back to fjs and I will I will do just post and now it has been imported for me and I will add two more posts so it's the post post and that's much better maybe we can do even the same for header so we'll cut it from here and let's do new file header.js and Export default function header and return and let's put the header here now let's use it inside our app.js header and it has been imported for me here so that's nice and everything looks really nice so now we can add some routing so let's here start by by putting some routes so as the routes yes as you can see it has been imported from reactor orthod on if Imports are not automatically for you you need to add those lines here but inside the routes what do we want to do um inside routes we want to First have our main route for our home page so let's do route and again it has been imported and this will be index route for our home page and then the element will be this whole main thing so um let's maybe try to end it here and let's see if we can just put it inside let's put it like this and this didn't worked yet but let's see we have routes we have our route here but the last thing that we need to add is we need to go to index.js and our app needs to be inside the browser router so let's do browser router like this and our app needs to be inside so now it works let's go back and yeah and this browser router has been imported for me here let's go back to MJS and we have our we have our first route that is indexed Route let's now add another one let's do a route and let's say the next one will be next will be a path to slash login and the element will be well let's say it will be just a day for now with text login right so now we have two paths and login link doesn't do anything because we need to fix it let's go to header and login should go to slash login let's see now it works but we shouldn't use the default HTML links instead we should use Link from react router Dom so let's import this one let's change this one and this one too yes that's much better let's go back if I click login and this doesn't work doesn't work because I need to change graph to two to slash register and I'm going to click now it works and as you can see on login page we have this login text that we added inside objs we can put here again page so we can see here right but the thing is that we want to put all the structure here as well so let's put this and instead of the post we want to put the div with login page all right but now as you can see we are repeating a lot of stuff and the main thing is actually that all the routes will have the main element and the header here we have in index route we have main element and the header and even on the login page we have main element and the header to get rid of this we will Define a layout so first first the main element and the header we will put it inside the layout component so inside our source let's put new file let's call this one layout.js and then let's do export default function layout and here just return and we just need here a main element and then the header and then then here we want to have our content that will change if it's home page then it will be have posts and if it's login page will have a form and stuff like this foreign to do this to do this with armor routing We'll add here an extra component called Outlet like this and it has been imported for me from react router done and now let's go back to fjs and as you can see we have two routes here but now we will let's say that from the login page we will just have only this div and no Main and header like this and let's say that for the home page we will have just just one post like this and now we want to put layout on our home page so to do this we will put another route here with capital r route that would be path with just slash and the element here will be our layout yes and then here inside we will put all those two routes and this and now we have layout we can make it shorter maybe like this and now as you can see we have index route here and route for our login page and those two are inside this main route that has our layout and the content from this element uh sits inside our Outlets that we put inside layout here all right so now let's go back to MJS and let's see um if I click this my blog nothing happens because I need to go back to a header and I need to fix this link so let's do link on the logo and it should go two and just slash so we can go back to the index page right back to appjs and let's fix the home page back so we can have many posts for now as you can see we have just a single post inside this index page but I think we can create a new component just for home page or index page and we can maybe create a different directory just for pages so let's do pages and I'll create new file here and let's go this one index page or it could be home page doesn't really matter index page.js and here let's do export default function index page and it will return um empty tag like this and I will just put the free posts inside like this and the last one we could change this one to div or make it empty doesn't really matter for react right and but now instead of single post we can put um index page here and it has been imported and now we have three posts and let's also fix the login page so um as the pages new file and let's do login page.js and Export default function login page this is a function and let's do return and let's put the div and assigned login page and now let's use it inside our app.js so instead of this login page inside div we will do login page like this and let's see if it still works yes it does so now maybe we can we have path like this maybe we can do the same thing here we can do it just slash login there's no difference here right and yes now I think we can put some content into our login page all right so let's go inside the login page and let's open our login page and what do you want to have here inside let's um remove this login page from here and then well inside we need a form and then we don't even need this there we can have just this form and inside form we need an input for username so let's say we'll have a placeholder that will be username and we need another one for a password so let's do input type password and the placeholder will be password and we need the button that will be we'll say login and that's basically it so we can actually do almost the same for register page but let's uh yeah let's let's copy this I will copy this and I will create a register page new file register page.js and let's do export default default function register page and let's do return this and for register to put the button will say register register and all the inputs will be the same let's go to app.js and we need to have a route for register so as the route path will be slash register and element will be register page register page and we need to close the route here yes and let's see register we have our register button so that is really good I'll make it back a little bigger all right and and what will be much better to fix the styling for login and register so let's see register page we have form with action and stuff let's do class name of register and same for login page we don't need the action let's do class name and let's put login okay so we have class name login and class name register on those forms let's go back to app CSS let's scroll down and let's say that form with login and form register and then we want to make them smaller let's say Max and wave of 400 pixels and the margin 0 Auto yes and now for the inputs let's make it for all the inputs doesn't matter if it's inside the form or not and let's make that input will be display of type block and let's add maybe some margin on the bottom of at least five pixels let's make it wave of hundred percent let's maybe add some padding of five pixels let's fix a border of um let's maybe do border zero and we'll add some background color of let's say DDD so those will be grayish maybe a a e sorry and I will add border on the bottom let's do a border bottom one pixel solid unless they're CCC yeah maybe we can go back to White and we can make the full border so it's the Border one pixel solid let's do DDD let's add some border radius of 10 pixels maybe a little bit less let's do five let's add some more padding on the sides of 10 pixels maybe less seven yeah I think this will be this will be good maybe we can make a wider border of two yes and now one more thing is I would like to okay the color is the default color is okay for Focus now for the button let's do button and let's do that default styling for those buttons will be almost the same as the wave of hundred percent and display will be block now as you can see the problem is both input even inputs and button is 100 but the width is different and this is because when browser by default calculates the wave it takes the wave that we Define it 100 and then in adds padding so we have defined this padding on the left and on the right to be 5 pixels and that's why those inputs are wider than the button but to fix this let's go to the top on our CSS and let's say that for all elements we will do uh sorry box sizing border box and as you can see the inputs are shorter because now for calculating hundred percent hundred percent of width it includes the padding on the sides so this is what many people most of the people use for calculating the wave and the sizing log sizing border box on all CSS elements all right but now let's see let's maybe add some some background color on the button as the background color now let's maybe do 555. let's remove the border to zero let's do a color of the text to White and let's make the Border radius of 5 pixels let's add some padding of at least five pixels and maybe more let's do from the top and the bottom is the 10 on the side zero I think that's too much Let's do let's go back to five maybe seven yeah I think this will work right now let's see we are at register let's see login login looks uh almost the same maybe we can add some headers here so let's go to register page and let's hear inside put H1 register to know where we are and for login page let's put H1 login yeah I think this this will work and maybe inside app CSS let's put that inside form if we have H1 it will be centered so let's do text align Center yeah I think that's that's much better right now let's go to home page login register yeah everything works so next part it would be nice to be able to register and login so let's go to register and then if I put something here like test test I would like to be able to register my user so uh for this we will need some back end so we will put some basic API endpoints to our API so first inside API we need an index.js yes and our whole react app is inside client and now we'll put index.js inside the API and here we will put our expressed JS up so first we need to install Express so um I will open my terminal we are inside maroon block that is this main directory we need to go inside apis as the CD API and now let's install Express so let's do yarn add Express now I think it's installed let's let's now use express so let's do const Express equals require Express and I can hide my terminal and the sidebar and now let's see let's do cons up equals Express now we can do up um to listen on Port let's say 44 000 maybe yes and let's put a test endpoint up get slash and now here we will have an arrow function with requests and response and it will respond with Json test okay and will be slash test endpoint right and now let's open Terminal and let's do we are inside API let's do node index.js and everything is fine but instead of node I will use node mod if you don't have it you should install it you can just Google how to install node mode or you can do yarn Global add or install node one and but node one what node does is if I do now node mon index.js every time I change something inside this file it will restart the app that our Express episode will reload so now I think it's working so let's do localhost on four thousand slash test and we have test okay and now if I do test okay too on the here on the bottom as you can see as you will see it restarted so now just now I just need to do refresh here and I have test okay too if I don't use node man let's do node index.js and I have test okay too but if I change to test okay free and I refer the browser I still have this okay too because I need to restart index.js no yeah now I have that's okay free and with no one it restarts the app automatically all right and but now back to our register page we need to have a slash register endpoint so that's the slash register and this will not be get but instead it will be post because we want to send some information with a post request and now now let's maybe try to send some post requests from our form from our react app so it will respond with a test okay free so I will hide the terminal let's go back to client I will react app source app.js and let's see we need to go inside our register page and well here we want to make a post request from here so first we need to fix our inputs and button and input so those will use state so let's do a const username and set username equals use State default will be empty string now same for password and now for the username I would do value equals username now I can't edit this because I need to add on change here and I will put everything inside the separate line so it will be easier to read for the on change we need to add as always for all inputs if we react with the event we want to do set username with event Target value and now same for the password and let's do value equals password and on change event set password event Target value one thing I need this now I can edit inputs and the values are inside the state so now I can add the and click on this button or maybe rather unsubmit on this form so let's do on submit and let's maybe create the function called function register and it will be called on submit on this form register we will get event here as well and we will run prevent default so we will not try to redirect from this page that is the default behavior of HTML or older of the browser so now we want to send a request post request so let's use maybe fetch for this so we don't need to install axios or other libraries Fetch and we want to do a request to localhost 4000 and then we need to add some extra options to fetch like first it will be method will be post and then we need to also send somebody and inside body will say that Json that we need to stringify and this Json will be just username and password like this and let's see because this is a Json we need to send some headers we'll send headers with content type of application Json like this and now I think we have all the data for this request because this is an async function we would do a weight here and we'll add a sync on this function right and now maybe I will open network and let's see if this will this will work so let's hit register and as you can see we get a course error back to our index.js inside API and we get this course error because let's see access to fetch at 4000 from origin localhost 3000 has been blocked because the course policy and you need to add this header to your backend app and the easiest way to do this to not do response header stuff to just install let's go to API and let's do yarn add course and this way we can do const course here equals require course and now we can do just up use course like this and now this will this should work let's see network clear this register we get 404 let's see why fjs register page okay we hitting we are hitting four thousand we need to hit four thousand slash register okay let's clear register 200 test okay free right and now let's maybe try to respond with the data we send because as you can see we are sending payload with a username and password so let's go to nfjs and here let's try to get it so from we want to grab username and password from request body but before we can do this we need to be able to parse this Json from the request and to do this we need to add another middleware so let's do app use and here we don't need to install anything we can do just Express Json parser like this so now let's try maybe to say that our request and data was an expert here username and password now if I hit register I can see let's see this didn't change I will refresh test test register a payload is okay this is the payload preview we get request data not we defined here and inside this username and password that is above test so yeah now it works so now we want to register this user and put this data somewhere over username and password so to do this I will use a database and you can use database on your local machine but I I'd rather use online instance because it's easier to set up and to browse the record so I will go to Atlas sign in and I will log in with my Google account for to create a free project here all right so now I am logged in and I will create a new project and let's call this one man blog next and create project let's build a database and I will use a free version you can do the same and the region doesn't matter for me I can just create cluster now we need to pick a username and password for this user I would do just blog and let's Auto generate this password we'll copy I'll put it for here for now okay I will change it later so you guys cannot use it let's create this user and and I think this this will work now let's see where would you like to connect from a cloud environment or my local environment I think it's good enough we will not publish it for now and you will just add my local IP and let's finish and close go to databases and our database is going to be prepared here I will hit connect and I want to have this connect your application so I can grab this connection string and then this connection string I will put it here as a comment for now and as you can see we just need to replace this password that I copied here so put this password here and yeah that should work now to connect with our database I will use mongoose and because it's the most popular database Library so inside our API let's do a yarn add mongoose and now for every collection inside our database we need to create models so inside our API let's create a new directory for models so we can create the first model that will be our user model so it's the new file and let's do user.js right and here we need to grab Mongoose so it's the constant mongoose equals require Mongoose like this and now we can create our user model so first we need the user schema so as the const user schema equals I think it was new and then Mongoose schema yes or we can do like this that will grab schema from mongoose so we can do just new schema and now and what do we need inside user schema we want to have a username that will be just a string and then but maybe we can Define some validation here as well so let's do username will be type of string it will be required and the minimum length will be let's say four and let's say it should be also unique unique true and now password will be types trick type string and required as well and well that's basically it now let's create the model so it's const or maybe we can do icons it will be good const uh the user model equals model either in importer from Mongoose like this we don't need to require Mongoose two times I will put model here and the first problem here is the name that will be just user and the second is the schema so let's do user schema and now let's just export user model so let's do module exports equals user model right now we can use our user model inside our index.js register so we can register users so first we need to connect to our Mongoose database so somewhere here on the top of our script let's do mongoose it has been imported connect yes like this and I will put this connection string here inside and this is async function so I need to put a weight here yes and let's see what happens now if I hit a register does it still work now we get some we get some errors failed let's see a weight is only valid in async functions all right I guess we can just remove this weight for now because this up post will be uh run late enough so the database will be already connected let's see now if I hit register yes we get 200 and this works now let's try to create our user so let's do user and I cannot automatically import my user model so let's do it here const user equals require and we need to go inside models and then slash user and then we need to do user and we can just do create parenthesis like this curly brackets and we just want to put username and the password like this we can put this as a one liner and this is an async function so let's do a weight here now it's red because we need to add a thing here and this will return our newly created user document so let's move to const user doc equals this and maybe you can just respond with Json user document to see what's inside now if I hit register for test test let's see what we get whoops we had a lot of we get ID we get test test username password so it has been created let's go and see let's browse collections we have user users here and we have our first user let's see if I hit again and didn't work and this is because this fade because our user needs username needs to be unique so that's why this didn't work to handle this error we need to grab this inside the try catch so let's do a try and let's put this inside here and let's do a catch and let's put this Json even here for this one run this Json will run if everything is K but if something is wrong let's catch the exception and let's respond with status 400. and the Json of the exception do we have a message let's let's maybe do just exception now let's uh clear this register again 400 yes and now we get some information about the error let's see yeah and so you see that we get 400 and we get Json about this exception so now let's maybe display some information about this error if we go back to register page we get this fetch but even dispatch we can put inside try catch so let's put it here like this and let's say catch exception so if something goes wrong let's do alert let's say Regis registration failed and try again later maybe let's see if we have some information about yeah we get that the username is wrong but let's say yes registration failed we will not say that then this username is taken for now let's see register nothing happened it's in the console we might need to refresh the test test register all right looks like we shouldn't catch the paid request like this so I will remove this try catch and instead we get the response here let's do a response equals and let's do just console.log response and let's try register again we can get response 400 and here we can do and as you can see response has even this okay false so we can do if a response okay is false then let's do alert registration failed and let's try again registration failed okay otherwise um Let's uh let's see maybe instead of okay maybe we can check status let's do if status registration status is not 200 because the default will be 200 then it will be register registration failed yes and otherwise we can create that and we can say that the registration succeed alert registration successful yes why not maybe you can change the order of this to if it is 200 then registration checks successful otherwise registration fail all right so now it will say registration failed but if we do test one and password test one registration is successful right so now let's maybe try a fix so we can login but the first thing is um we put the password as the here as a clear text and we shouldn't do this instead we should encrypt the password first with their Crypt so let's do yarn and let's install backcrypt back crypt.js let's use this one and I will do yarn add back crypt.js and let's see how to use it just like this back grips require so let's go to our index.js and let's require backcrypt like this instead of our let's do const now as you can see to create uh to Hash a password we just need to have a salt maybe we can Define it ourselves as the const salt equals um something random string maybe like this and and now to encrypt the password we just need to do answer here hash sync and then our password and assault so here let's see here we are creating a user with username password but instead of putting just password to be password we will do the password will be decrypt and here we need to do hash sync hash sync and here we need to put the string that will be our password that is just password and the salt is just sold yes and this should work now let's remove our user so to refresh and I will delete those two users this one and this one and now let's try to register register and user test test register registration failed oops that's not good let's see why let's go to network we get 400 let's see 400 we don't see any information maybe we will do console log on this exception to see what's uh what happened let's hit register again and let's see we get invalid invalid salt version right so it looks like we just need to generate our assault this way so let's grab this and let's paste it here yes like this generate salt to sink and now let's try again register registration successful now let's refresh connection and we get our first user with with a password that is encrypted or hashed yes so now we should be able to to login so let's go to login and now let's fix our login page so inside Pages login page here we need to fix the State as well so let's do const username and set username equals use State default will be empty string same with password set password default will be empty string and for the inputs here we need to do value equals username and then on change will be event set username event Target value now same for the password value will be password and on change it will be in event we have setter set password even Target value now I can make put those into separate line so it'd be easier to for you to read yes right and now we need to add the on submit on this form so let's create a function call the login and let's put this function here we will have an event here as always that we need to run prevent default on and now [Music] um how we want to handle this login same with the wave registration let's do just fetch HTTP localhost 4000 slash login and then extra options method post and body will be Json stringify we want to send the username and password yes and we need to send the headers content type application Json and that's it this is a weight here and async here and then now let's see login and we don't have an endpoint yet so let's go back to index.js we have register but we don't have a login so I will do up post and slash login and here let's do Arrow function with request and response and now um let's first grab our username and password username and password from request body right and now so how do we want to do this first we need to grab the user with the c username and then we want to check if our password off is the same as this password that we have inside database but is encrypted so first let's grab the user let's call this one user doc user document from our database and let's do a user find and we want to do a username is same as username but because those two names are the same we can do just username and we want to find only once as to find one and we need to add a weight here and a sink here all right and maybe we can now respond with Json with this user doc to see if it works login test test login 200 and we get this our user so now we need to compare our database sorry password so to compare to compare we need to run just something like this and the inside hash we need to put user doc that password and this is the password from the database of this user and instead of this weird string we'll put the password and this password is the password from our request and now the result will be true or false so let's put pass OK equals this and let's let's respond with Json and let's put pass okay here now it's tested and let's put test test login and we get true because the password is okay if I add something here let's see make it false because the password is incorrect all right so when this part works now the next part is to have some kind of session or a token so now if the password is okay and then user is logged in I'll add logged in comment here otherwise else not logged in so let's maybe respond with status um status 400 and Json wrong credentials yes but if we are logged in then we will respond with Json web token so um first we need to install Json web token so inside our terminal here API let's do yarn add Json web token like this enter and now we can use it here so the const JWT equals require Json web token yes and now with Json web they can instead of returning just Json with a text we will respond with Json but we will put uh we'll send the token so to create this token with encrypted information about the user we will do JWT and then sign this is a function here and first we need to send the payload what do we want to have of information inside our token I want to have a username of my user so let's do username I will put username like this and maybe the ID of the user so the ID equals and let's grab this from user doc dot underscore ID and then then what else do we want to we want to have here the second param for sign is our secret or private key let's maybe create another salt here for our Json web tokens let's maybe call this one secret and our secret really some random string so let's put it here and now let's put secret secret here and now this is async function as well so we can either do a weight here or maybe we can do then here or um or we can do third program as the options can be empty and then we can put a callback here like this and this will work as well I think I'll use callbacks and inside this callback let's see what's inside the definition of this in this callback we get an error even information if there's an error or we get the token if there is no error and I assume that we don't have any errors but if we do have an error I will just throw it here but otherwise I will do just respawn Json and the token right now let's try to log in with test test login and let's see and we get this we are the string in the response now uh to have this string and to send it every time we do a request from our app I will send it as a cookie not as a Json back but as a cookie so let's do a response cookie and let's say the cookie name will be let's do this again cookie the name will be token and the value will be our token like this and we'll put the Json okay right now if I hit login let's see 200 it says okay but inside headers let's see inside the respawn headers we get set cookie with this token information here all right so now let's go to our login page and here we have our login and now the important thing is we want to save this cookie inside our react app to do this inside our fetch request we want to add credentials to include so that way if we have any cookie it will be consider us credentials and it will be included to our browser and included in the next requests if we want it or even send here right so let's uh now do test and test again nothing has changed oops we get a course error and this course error is because if we send credentials so as you can see request headers we don't see cook is here yet but let's go to index.s and let's see we are using this course thing here and the thing is that if you're using credentials you need to specify more information like let's open course documentation course and for credentials you need to set it to true so let's do credentials to true and you need to define the origin and origin for us will be the host of our react app so I will copy this and I will put it like this HTTP logo has 3000 maybe about this slash at the end now let's clear let's put test test login and we get 200 back response headers we get the token and even in the even in the request headers we are sending this token that we had before so that is good now maybe instead of doing this response okay or maybe it's fine with okay but inside our login page we can do now something if the login is successful so first let's grab the response const response and now if response sorry if response is okay then we want to say login is successful and we want to redirect to the home page so now to redirect to the home page we need to first put it inside state so let's do redirect and set redirect and default will be false now if the response is okay we will set redirect to true and this way inside our render part so here where we have return and this all the HTML here we can do if redirect then we can just return and here we want to use navigate to as you can see this navigate has been imported from reactor to Dom navigate to and let's say we want to navigate to the home page yes so now let's do test and test maybe first we can add if the response is not okay else alert uh wrong credentials something like this and let's do test one here run credentials and if I remove and I try with test test I have been redirected to the index page so now um we're logging and registration works so now the next part is we are logged in so we shouldn't see this login and restarting on the home page right right so this login and register is actually on inside header so let's see uh it's here header and we have this login and restarting instead we should check if we are logged in right but how can we know if we are logged in we have a token inside our cookies but well anyone can have a cookie and set in the browser so we need to check this token if it's valid if this token is valid and we need to create an endpoint for this and inside our index.js inside API let's create an endpoint for this called the profile and it will be a get request this time slash profile and it will just return profile information as the request response like this and now let's maybe first respond with the cookies response um with request cookie cookies like this but um this will not work yet because first we need to add the middleware with a cookie parser so let's do up use and we need to add a cookie parser so let's search her what is the name cookie parser yes cookie parser so let's do yarn add cookie parser and let's add it here so that's the const cookie parser equals require quirky parser like this and I think it's the Jazz cookie parser called uh like this and now we should be able to read the cookies let's see if this will work and we need to call our slash profile endpoint so inside our header let's maybe do a use effect here an arrow function and the second param will be empty Square parenthesis so this will run every time we Mount this component so let's do here Fetch and the endpoint will be HTTP localhost 4000 slash profile and do we need any params that yes we need to send the credentials so the credentials include and let's see if I open my console here let's do a network and let's reload we are running this profile endpoint and we get the response with all the Q Keys we are sending this token so inside our index.js we can grab the token so the const token from request cookies and then well now we can try to read this token because as you remember it's a JWT token with username and password with username and ID that we can read only if we have this secret so we can only read it on the backend side so let's do this um that's the JWT and verify and now the first is the string tradeability string that is our token and next is our secret so let's put secret here and then options I will put empty object and the Callback I'll put Arrow function like this first param inside our callback is error and then we have our information here so if we have error I will just throw this error but if we have the information let's do response Json with this information and I'll get rid of this responsation here and we'll clear this console let's reload profile and we get our information so this is what sits inside our token and this is encrypted and this sits inside this token text that we have let's see it's here inside this we have all this information the ID username and EO tier issued at IIT so issued at is when the token has been created and I will not use it but it's nice to have in in case you want to invalidate tokens older than some kind of date all right but now we have the information and we can return it but instead maybe of returning the ID and the test and the username I don't know doing it I didn't username maybe we do so yeah let's just respond with the old information we have so let's go back to our header and let's see this is fetch so we can either do a weight here or we can do then this time I would do then and we get a response here so I'll do a function like this and then this is adjacent so we need to parse it from the response first Json and this is oops and this is an assign function as well so we need to either do and await here or we need to do that then I will do that then this time and with the Json that has been parse Json information inside this Json we will have all this information we can maybe rename it to user info all right inside user info we have username and ID well and we can put the username somewhere here maybe so let's put it into state so let's do username and set username equals use State default will be empty string why not or maybe no and this way um let's see here we have navigation and let's say that if we have a username username and then we will have parenthesis and we will put empty tag like this and we will put a link that will be to create a new article link 2 and create new article something like this create new post but if we don't have username and then we will have a parenthesis not div we'll put empty element for react like this and those two we will put them here now let's see we have login and register and but here we forgot to put set username and from this user info we need to grab username so user info dot username and now we have this create new post but we should have cranny post and a log out as well so I know it can be a link I can be let's do this as an attack for now log out yes so we have if we are logged in we have logout and create new post now if I refresh we are still logged in so it would be nice to maybe first fix this logout functionality so um let's add maybe on this uh a tag on click and it will be logout function that we will Define somewhere here so I'll put some spacing here let's do logout function log out and well with the logout function we want to invalidate the cookie so let's do this we can either reset the cookie on the front end part or we can do this with the backend I think it will be better to do this on the back end so let's do Fetch and hdb localhost 4000 slash log out and the credentials need to be sorry include here include and let's make it a method of post right and now let's go to API index and now let's do app post slash logout here Arrow function with request and response and let's see um here we just want to respond with cookies cookie token and when we are logged in we are setting the token to the real token but this time we will send the token to be just an sorry just an empty string and we will send the Json okay right so I will clear this console if I click log out we have logout here okay we have headers response headers and I think it looks good enough if I refresh we are not logged in anymore but let's login let's do test test we are logged in yes but we need to refresh we will fix this later but the first thing if I hit log out I want to invalidate my token and I want to reset this username so let's do a set username to know this way if I hit log out it will refresh this part right but now let's fix if I click login here and hit test test and I click login uh the header is not updated and another thing is the information about logged in user shouldn't be stored inside a header component but rather it should be inside a context so to fix it I will create a user context so I will put a new file inside the source and I will name it the user context Js and inside I will put just const user context equals and here we will just do create context from react and default will be just an empty object and I will just export this like this export const user context yes and now let's go to our index.js inside our client source where we have our react app and I'll put this user context here but before I will do this I would Define a printer provider so let's do const user context provider equals and it will be a function maybe we can do just like this function um provider user context provider and it will just return all the children children like this we will grab the children from this and now let's do export function user context provider and if we put it inside the source uh sorry client Source index.js it shouldn't do any harm so let's see maybe we can skip this part and put it inside app here so let's see if we put it here user context provider and let's put all the routes here inside let's refresh this didn't work because well children didn't work let's see children should be probably Capital C now it should be small see No it should be Capital C like this and Google see okay and we shouldn't um return like this let's maybe instead do div and children like this all right the error is because we shouldn't put tuner like this instead we should put children like this not as a component and let's see small C here and small C Here and Now everything works and that was my bad uh now let's see and we have this user context provider and here instead of this div we want to do user context dot Pro wider and now value equals empty object for now but we will have a state here so as the user info and set user info equals use State default will be empty object and we will provide this user info here right so um we are let's provide user info but let's also provide a set user info with our context right now if we go back to our header instead of having user info username inside our state here we will use context here so instead of setting username to the state we will grab the set user info from our contacts so as the const set user info and we will grab it from use context from user context like this and the set user info with user info and here instead of set username with the set user info to maybe know yes now username is not defined here but we can grab it from there use we can grab user info here and check if we have a username username is actually inside the user info so we can do username equals user info dot username but because user info can be sometimes new but we'll do a question mark here right so now we are logged in if I click here we are logged out but back to login if I do test test we will be redirected but this will not be refreshed to refresh this let's go to login page and if the response is okay let's see what we get of the response from the login we get okay uh instead I would like to have inside the Json I would like to have the the user ID and the username username we have actually here but user ID let's go to API index.js and let's see we have a login here and here we are sending Json okay instead of this okay I would like to send the ID and it's inside user doc dot underscore ID and let's send username back why not username like this now login test test login and let's see we get the ID well that's good let's go back to login page and we are doing set redirect to true but first from the response we want to parse the Json and then let's do then and inside the Json we get all this user info so let's maybe call this one user info here as well Arrow function because this Json function is I think and we'll put this redirect here and before read redirect we want to set context information so let's do const and the set user info and we want to grab it from use context and here is their context like this and here let's do set user info and we can just do user info that we get from the Json all right so now if I refresh I'm logged in but let's do logout login again test test login and we are logged out we are logged in and we are redirected to the home page so that works now so and now we have a working login redirection and logout functionality now the next important thing is to have this create new post functionality so let's go to our header first and let's see it should be a route on slash crate so if we click on it it's just white because we don't have any 404 page we can fix later but first let's go to app.js and we need to add a route for our great new post page so maybe we can actually create the page first so let's do new file here inside pages and create post dot JS and here let's do export default function create let's do the same as the name create post and let's do return and it will be a div with here you create your new post and let's go back to app.js let's put a new route here so let's do route and the path sorry path path here will be slash create and the element will be our new recreated page so let's do um create post yes and let's close this route like this and now we see here you create your new post and here we want to put a form for creating a new post so inside the each post we need to have an image we want to have the title and we want to have a summary of the post and then we want to have a Content like all the texts and stuff so let's create this form so here inside we need to put a form and well let's see inside this form we need to have an input for the title and let's add a placeholder title whilst we need the we need another input for summary so let's do summary placeholder will be a summary yes and then we need also the image so let's do input type file yes it's in Sweden but you get the idea it's just a button for picking the file and then we want to have a text area text area for the rest of the content but to create like more Rich content we would like to put headers and more paragraphs and and stuff so I think it would be much better to have like some kind of what you see is what you get editor and to do this uh we will use react quill I don't know if I spelled it well re-react coil and this is one of the most popular editors I can show you here live demo and this is the editor so we can put yeah images you can put headers and stuff so this is what we are going to use I'll open here and we are inside the API let's go back to Marine block and then CD and let's go to client and inside our react app let's yarn add and let's add react quill enter okay now it's installed so um now now let's use it instead of this text area let's see here and I will remove this text area plus this for now instead we will use react quill like this and let's see what we will get like really weird and huge buttons and this is because we need to import styling for the editor as well so let's do import and inside react react uh quill we need to go to this distribution and when you want to import this snow theme they have different themes but I will use this snow and here we get the the editor so we have headers and and stuff so by default you see header one is centered this is because we said that all the headers inside the forms need to be centered let's fix it here form H1 should be centered instead let's deform login H1 and for register H1 should be centered this way if I put and the one now it's to the left right and so we have this editor the last part is we need a big beautiful button so let's put it here button and then let's call this one post um or maybe create post yeah and we would like to have some spacing here between so maybe I will just put styling directory here margin talk will be 5 pixels yeah I think this will this will be good this will work right so now um we need to fix state for those two and this for our form so let's do const and first will be title set title use use State default will be empty string same for the summary summary set summary and then the content so let's do const con 10 set content let's do react quill value equals content yes and now we can actually add more options here to this react quill by putting modules yeah and to define the modules I will just copy paste it from the website they have um they have let's see modules modules let's see this is uh all the modules they have I think so let's grab it let's do a const modules like this and here I put like this toolbar okay like this and now yes modules equals modules we can put also formats inside if we want yeah why not let's do a const format equals and let's put it like this without this equals here and let's put formats formats sorry formats equals or mats and see how it looks like now it doesn't work let's see why if I refresh all right now we have it back right so now we have even images and stuff so uh so that is really nice right but first we have um now state for those two first inputs so let's fix it maybe first we can grab those modules and formats and those don't need actually to be even inside this create pose function so I'll put it here and no first the value of the title will be title and let's try to like this title like this and then we have on change that will be event and with this event we'll do set title event Target value as always I will try to put it in different lines so you guys can see it better and now same for the summary of the post and the summary will be this part so this some kind of intro to the Post uh so let's do here value equals summary and on change event we have set summary event Target value yes and now we have value on this react quill but we need to do on change event set content event Target value sorry here we have value let's put in different line this on the next line as well like this and like this here maybe we don't have a Target let's see react quill Let's do let's see react wheel let's search for on the change okay [Music] um first on change on change we get just the new value so we can do new value like this and we can do just new value and now this this should work let's see I will refresh test test test right looks like everything works so uh the last state that we need is for this file so um maybe first I will download a file so let's go to here and I will save this image and now create new post pick a file and what the what should we do I want to pick this image and upload it to our server or to our API let's say that inside the API will have a directory with all the uploads and when I pick this um when I pick this image I want to display it here above and I want to I want to send it when we create the the post so I can pick a file here the only thing that will happen is it will put the file name here uh but that's basically it but I can put the title and test summary test and the content here will be test and then we can either do that this file will be uploaded even before I click this create post or it can be uploaded when I click the create post I think the easier way would be to just upload it when we create the new post and to send all the information all together so um inside our create post page um actually we we have create post but the rest of the pages are have the page in the name and create post is the only page that doesn't have the page in the name and that's maybe not that good but doesn't really matter right but here we have this button create post and this button will submit this form and we want to do that on submit we want to create new post so let's create a function called create new post all right and we will call this function and submit here create new post and as always we'll grab the event and we'll do print default on the beginning right when we click this create post what do we want to do we want to grab this this this and the file and send everything to API endpoint right right so let's maybe start by sending here everything to the non-existing endpoint it will create the endpoint later so let's say that we will send a fetch request to HTTP localhost 4000 or 1000 slash crate maybe slash post all right and let's add some extra information to this fetch request the method will be post because we want to post a new post post new entry or post new entry blog uh post new blog entry right and we want to send some kind of information so that's the body and here we can send a Json but and because we have this file that we want to save as end the easier way will be to send all this information not as a Json but as a form data so here inside our create new post I will create an object called data and data will be new form data like this and this way we can do data set is it the data set data that set yes and we want to set title to title and we want also data not date data set the summary to summary and also the content data set content to be the content and data set and now the file to be and the file from here but how can we access it we need a state for this so as the const and let's do file and set file you state let's say that default here will be empty string as well here we need to put comment for now same here and let's fix the state for our file we have file here let's say that the value will be file and on change I'll put this into different line we get an event and we want to do set file to maybe not even Target value but event Target file files like this right and this way I will maybe let's uncomment this body I will command this Fetch and let's see what's inside the file console log this file state let's see maybe it should be actually files and set files instead because one input can have different many files sorry so let's do console log files and let's see something is wrong here file is not that defined here should be files all right I will open my console here and let's see if I pick this then it didn't worked find to set the value property let's see set files we probably can skip this value files put it like this and now if we pick this file and now if we hit create post we get file list and this is this console log that we get here so we have files and we have one file here of index 0. and yeah we get all the information like the name and the size and stuff like this so we will send this one file here we will see set a data set file and we'll grab files of index 0 because we want to send only one file even if you pick many files here we will just grab the first one right and I will close this for now and then now I will uncomment this and now with this fetch instead of sending Json we will send this data like this this form data that we have prepared here well let's maybe see how it looks like some I'll open back my console here let's open network let's put test test and let's pick a file here and test here and we get 4 4 cannot post to slash post because we need to create our new endpoint so inside our API index.js we need to create another endpoint for up post request to slash post let's do request response Arrow function and here what do we want to do and we want to let's see payload we get title summary content and file that is binary file um first let's say we want to save it this file to our uploads directory so to do this you'll grab the file from the request and we will need a library that is called monitor if I spell it correctly and so let's open sorry here and let's open Terminal I will go back to API so let's just see the API and I will install the monitor so let's do here not motor I don't know if I spelled it correctly and yes and this is how we how we use it so on the top and we can grab it like this motor equals require monitor and then we can Define our our upload our upload middleware so I can put it same way they have it and but let's rename it to upload middleware right so we have our upload middleware and we want to put this upload middleware and inside our post so as you can see they have upload here and they are putting it like this upload single file and the name of the form data is Avatar for day for what they have for us it will be here we will put upload middleware dot single and the data label that we have is a jazz file if we wouldn't rename this file to Avatar then it will be Avatar but for now it's just a file all right and this way in the in the request we will have some more information about the file like a path to the file inside our uploads and stuff like this so maybe let's just respond with Json and all the information from the request file I think it's uh this way request files and then file I think it's like this right and now let's see if I hit create post here we get 500 so there was some kind of error let's see cannot read property file of undefined let's see if I do just request files and let's hit create post again 200 preview didn't work let's see if I create post Let's uh let's add maybe a weight here and let's grab the response spawns equals this and we need to add a Sync here as well let's try again create post nothing happened let's clear this try again create post 200 payload let's say method post it should go to 4000 slash post all right let's see we get something inside our uploads we get some files but well we don't get anything into response let's see why let's go back to index we should respond the wave Json but looks like this doesn't work let's just maybe refresh test test test test and let's pick a file this one I will clear create post looks like this worked but we don't get any preview let's see create post I think this is the previous thing because we don't send any we are not parsing the response let's try to pass the parse the response so let's do the const um let's do just response Json let's parse it like this and let's do a weight here and let's put it inside the console log and now let's see we should get everything inside console we get some kind of error let's see network post let's try to send again post 200 let's go to API let's see let's maybe try to change it to Jazz okay create post then we have okay if we then replace it to files request files to see if we get anything it's empty if we just send the request file maybe it should be file let's send okay then we get the files so in these files if we do request file we get the file name that is this and with bbd30 so it's um BBD 30 so it's this one but as you can see the file name we have now is a little odd so we will rename it first so and we don't want to have it this way we want to have maybe add dot jpeg or dot a web P so it will look like a regular file and we can open it so we want only to rename it and to add that web P that we have on the original file name so to grab the extension from original file name maybe first we can grab all this information from uh or maybe just original file name so I will do copy and like this equals let's grab it from request request file and now in the original name we have this and let's say we want to take this original name and split it with dots and we want to grab the last the last part so just web p so let's save it into Parts like this and then let's now Define extension equals and this will be the last part so let's do parts and here Parts length minus one so now we can do extension and if I put like this create post let's see extension web P so inside parts we have two parts so this is an array the first part is everything before the dot and the last part is web B and now the thing is that the we want to rename this file to uploads slash this name and we want to add dot web B on the end so to rename the file we want to and we need to use FS Library so the const fs require FS FS is from file system and now we can do FS move or rename sync all the path will be in this path so we can grab it from request file path so let's do rename sync path and the New Path and will be path plus dot plus extension all right now if I click create post uh let's see we get the extension but we get also this file name with the dot web p in the in the file name now and I think that's that's much better because we can preview files right um but maybe this new path we can save it inside a constant so the constant New Path equals uh this oops cut from here put here New Path right so here we are done with the file and we want to save it everything from the payload so title summary content and the file that we uploaded or the link to the file we want to save it to a database and for this we will need need a new model so this new new file inside models let's call this one post dot Js and here we will do we will grab Mongoose so let's do a const mongers require Mongoose and first we need schema so let's do Post schema equals uh let's grab the schema uh class from schema class from Mongoose like this and we will also need model later let's do here a new schema and let's define our post schema so our posts need a title that will be just a string same with summary that will be a string as well and same with the content I'll be a string and then we have a file or maybe an image doesn't really matter maybe we can call it the cover well string and because this will be a path to a file inside uploads and that's it but there's one thing we can add we can add another parm here that would be an object with extra options and we will put time stamps to true and this way we will have an extra two columns we've updated at and created at and we will know when uh post has been created so now let's export it and let's create a model first let's do const Post model equals model function and the name will be post and the schema will be post schema like this and now let's do export sorry module exports equals uh post model like this now let's go to API index.js let's grab the post model so the cons post equals require models post let's go down and now let's see now we can here we are uploading the file then let's create a post there's the post dot create and here let's put all the information so we need to grab from the request first we want to grab here title summary content title title summary and the content from request body I guess maybe let's first con resp let's respond with this to see if this will work summary and content let's hit create post let's see preview yes it works so now we can create the post with title summary and content and as you remember we have also cover that is our image so let's do a cover and cover will be at our new path to the file so let's do A New Path and like this let's save it this is async function so we need to do a weight here and we need to do also add a thing here on this Arrow function and this will return our post document so it's the post document so document from our database about this post and subdocument from our database yes and let's maybe just respond with Json with it so the post doc let's save it and let's see if I click create post it looks like everything just worked so uh if everything worked then maybe we can redirect to the home page or redirect to the um to the post page so um let's see if we have those posts inside the database I need to refresh here and we have posts and we have one post with the cover and stuff so now maybe let's print all the posts from the database on on our home page so um first I will add that and if we add the deposit will redirect us to the um to the home page so let's go to create post page and here we are doing just console log but instead we don't need the response here maybe we do we will check if the response is okay and if it is we want to redirect to do a redirection we need to have a state for this let's do redirect and set redirect default will be false and here we will do set redirect to true and here where we are rendering all the HTML we will first check if redirect is true then we will do navigate to just slash so to the home page and we'll return it like this right so I can create another post test test I've got this too and let's put the same loan mower again create post and I have been redirected to the home page and those slow Motors are not from the database yet but we will fix it now so let's see app.js we have our index page here and as you can see our index page is just a free posts that are hard coded to the to the code so to fix it we need to do and use context here as sorry use effect that will run when we Mount or when we yeah when we Mount our component so when we Mount our home page we want to run this function and we want to grab all the all the all the posts so let's say that the when we go to slash post but this time it will be a get request not post requested we get request and we don't need any power arms feeling I think as the const response here fetch post maybe we can do that then all right we get a response here and what do we want to do with the response response will be a Json and this um this the Json that we get off from the response will have all the posts for the home page so let's call this post and now um let's maybe just console log the posts posts like this should be Json like this it should be Json dot then that then because this Json is the an async function so we need to run then and this fetch is also as in function that's why we have that then all right so this should work we need to add endpoint on get request on slash post so let's go to API index and let's see let's we have post requests on slash post but now we are the get request on slash post and get request is default that's why we don't need to define the method on the fetch inside our reactor here we have a requests and response and well we just want to respond with Json with all the all the posts so to do this Let's see we will use our post model and we want to find and we want to just find everything so let's do just fine and let's put it into const posts equals this but we need to add a weight here because it's an async function and we need to add a Sync here on our Arrow function and let's just do response Json with posts and this will work but it can be simplified we can just put it like this and we can get rid of this line so now if I open my console let's see looks like it something didn't work let's open network and let's see if I refresh let's go back to index page and let's see oh sorry it shouldn't be slash posts it should be first localhost 4000 slash post like this so now console and we get an array of two posts so we can set it inside our state and we can actually display it here so let's do const posts set posts equals use State default will be an empty array and let's do set posts posts from our Json that we get here and then here instead of printing posts like this we will do posts if posts length is bigger than zero then we will do a posts map and with each post we will do the let's do parenthesis here and we will do just posts like this and let's see now we should have only two posts yes we do and this post information is not used by our post component but we can pass all the properties from Posts like this and this way let's open post we again grab all the information here it's our title summary and cover and what else um we have all some content I don't know if we are going to need this and that's it and let's nowadays play all the information so title let's build the title here into H2 title summary let's put a summary here summary and now as you can see there is one thing I forgot about our username Creator or author and this let's see if I open my network Tab and I refresh on slash post we get those posts and we get created that that we can use to display here so let's let's use it it's passed here as well so let's just grab it created at instead of this time let's uh let's put the created that it looks weird for now but we'll fix it later or maybe let's fix it first so we have this weird created that that we want to make prettier the easiest way would be to remove this T and remove this Z and display it let's put this page here um but there is a prettier way of doing this there is a lab called the react time ago and that I like to use and it takes the timestamp and it prints like 45 seconds ago or stuff like this I don't know if it would be better to have a date or to have a five seconds ago maybe it would be better with a regular date so for this I will install date functions this one so let's go to this one let's go to a clients so let's do a client see the client and now and let's do yarn add date FNS and inside date FNS there is a function called the I think it was format ISO 9075 in let's import this from date FNS and this will format the same format to the same format that databases MySQL is using so let's do create that here let's see if this will work and now it did not maybe because this function needs a date so that's the new date and let's put it like this now it works now as you can see it's the same date that MySQL databases uses so it has this date and then space here and time they have much more functionality if you would be interested this is really helpful Library so we could actually format in different way so instead of format I saw this we can grab format function format and then well maybe we can use the month name like this one let's do mmm and maybe the date of the the day of the month like this and then maybe the year so let's do let's search for a year let's take the full year like this after coma and then let's take the time hour from 0 to 23 like this HH colon and then let's do minutes this way yeah and now let's see let's refresh didn't work format let's see it takes the date and then the format so this should work see what is wrong use a lowercase all right now it worked so we get two posts and the the date dates work but anyway I think that the format ISO 9075 looks better so I'll put it back and I will get rid of this formatting all right but now and the next thing that we need to fix is actually this uh this username it shouldn't be my name but instead it should be my username and but the problem is we are not saving the outer ID here so let's go back to API index.js and when we post to a slash post we are creating a new post but we are not putting out our ID here so uh let's first go to post model and we need to add author here and the outer what will be the outer the outer will be of type ID and to do type ID we will need to do schema types object ID and because it will be a reference to our users our other reference cool on and user as a string here right and now this way we can go back to API inductor yes and here we are creating a post we can add the author and here we need to have the ID of the user how we can grab the ID we can grab it from Json web token that we are sending when we are creating new a post but let's uh let's see if we are doing this in the create post we have this uh fetch but we need to send credentials include here as well so we'll send the cookie and now we can grab the Json web talking cookie here so and same way we did it here JWT verify and we get the information but here inside after we get this token information we need to grab the token here as well so let's do token from request cookies uh yes this way and we will put this creation of the post here and even this response Json and we don't need to respond with the info from there from the cookie uh let's see here we have some weight so we need to add async here and even for uploading the file and renaming the name well that's a really matter where it if it's inside here but after we verified the token we get the info inside this info we have the ID so because it's user info you can we can do info dot ID let's see if it's dot ID yes it is ID will be user doc underscore ID so this should work let's try to create another post test free and test let's pick this long motor again test create post we have this test free let's see inside the database if I hit refresh here and see and where we have refresh here refresh Test free and we have outer object ID of this it ends with 097 and then my user is 097 ID so that's correct now I will delete other two posts because we don't need them I'll delete this one so it's deleted and this one without the outer so we have only one post with the outer uh but if I open my network tab and Let me refresh this post we're sending all we are getting only one post and from the outer information we get on the ID but because we added this reference to the user and we can now do something like this post fine and we can do populate with user information now we find refresh let's open post it didn't work let's see maybe because we need to put it like this let's refresh no this didn't work let's put it as it was find it to fetch and see network okay looks like we have maybe should be smaller small U sorry it should be user it should be author because this is the Pro person name okay and let's open post we get one post and now instead of outdoor we get the password and the username and then but maybe it would be fine with just username we don't need to grab and send the password even if it's encrypted so I guess that here we can Define what kind of information we want to select so let's try with username maybe like this I will hit refresh and see outdoor we get ID and we get only username no passwords we don't need to show the password in the response even if those are encrypted and it's not a problem right but now we have the outer here that we can use inside our post not here inside our post inside our client so inside our reactor we have a post we have the author here that we can grab and instead of my little name here I can do outdoor dot username so now we have test instead of my name but if I log out and register with Test 2 and password Test 2 register and now I can login Test 2 Test 2 login and we can create new post test to post and test and let's put maybe let's do the same file test crate and test to post as you can see it has different outward in this one so yeah this works one more thing is I would like to change the order of the pose the last one should be on the top so let's go to index.js inside the API and here where we are selecting all the posts let's let me put it like this and now let's uh let's maybe put this populate on the new line as well here Let's do let's add a sort and let's sort by create the Hat minus one so it will be descending if I refresh now we have post two on the top and another thing I would like to add is to limit name it to 20 latest posts in case there will be 5 000 posts we want to only select 20. right um so now we are selecting posts uh let's see we need to also put the image so I will create a new post but first I will grab an image from unsplash maybe I can grab it from here um I will save this image and I will copy this and I will put it here and I'll put a test here let's put this image from here test create and then the image is not used so let's go back to our client Source post as you can see the image is hard coded instead we get the image from the cover so we have this cover here that is not used so let's use it here in the source of this image Let's Do cover but it's not inside our react app let's see you see this didn't work because uh image it's not inside uploads this it's not inside the if I open this in the new tab sorry I can do maybe oh I cannot open this and this way it tries to find it in the local as it has three thousand but it should search in localhost 4000 instead so um instead of doing it like this I put a string here http localhost 4000 plus discover information slash and then so now we have localhost 4000 slash upload slash this all right so now let's see if this works and this didn't work because we don't have an endpoint for this but how we can create endpoints for all the file names we can do something called let's see we can serve all the static files from uploads and to do this we need to do app use and then Express Express static and then the name of the of the directory so let's do not public it should be uploads now let's see if I refresh didn't work let's see I think it should work slash upload slash this let's uh see here maybe I will just restart this app so this doesn't work 4 000 uploads and this let's see if we have this file uploads and we should end with a12 we have it here so it should definitely work let's try to put it different way let's use up use and let's do Express static and first we will actually put the slash uploads and then we will put Express static static and to be sure that everything works we will put the current directory name and we'll add the slash uploads and now I hope it this will work oh sorry this is all right appears on slash uploads X not export static should be Express static and now everything works yeah so the problem was only that the unit because we have this project inside the mirror block that's why we need to add this way that with this directory that we are currently running at the on slash uploads and we are home right but now let's open our react app and refresh and our images are now working so the next part is actually so we can open a specific post and see the rest of the content so um let's see um if we go to app.js and open index page we have all the posts here and we should be able to click on the image and on this title so the image should be inside uh inside the link so let's put a link to the link should be to a specific post so to slash post slash and the ID and the image should go inside and same now for the title title should be maybe I can just copy it from here and the closing link should go here and the link hasn't been imported for me so it's the link now it's imported and now it's uh not that pretty anymore but we can fix it with app CSS let's see and this is some kind of H1 so I guess it's this one takes H2 and so let's do text decoration um none div pose div texts H2 now we need to style something else we need to go to div post div texts and attacks so all links should be text decoration none all links inside this div post should be the execution down and color let's do inherit yes that's uh that's my number now let's fix the links so those links should go to the ID of the specific post so from here we can grab underscore ID and because when it comes from database it's underscore ID and now instead of this we can do backticks slash post slash and whoops and then let's put the dollar sign and let's put our ID here sorry it should be underscore ID right so now as you can see if I click it goes to slash post slash and idea of the post all right so now let's uh let's define the route for this so in app.js we have routes here let's define another route path and this should go to slash post slash and then the ID of the post so let's do colon ID and then element we don't have an element for now so let's create post page as the new file inside Pages post page.js and then let's do export default uh post sorry function first post page like this and here just return and uh as the div and post page here and let's use it so element element equals a post page like this it has been imported for me let's close this route and we have a post page here all right and we are logged in and everything works so now let's fix this post page so we get the ID and the first thing when we are when this page is mounted we want to grab the information about this specific pose so let's use effect and the first program is the arrow function will be in the function that we want to run and then dependencies we have no dependencies empty array because we want to run this function when our post page component mounts and now we want to do Fetch and we want to fetch to http localhost for 1000 slash let's say post and then slash and the ID of the post but how we can grab the idea of the post and there is a function called I think use params in react router yes the const params equals use params and then let's do console log params and I think well let's say cannot use params cannot be called inside the Callback right not a problem we can put it outside of the Callback now let's see if I do inspect console we have an object of ID and then an ID so instead of params we can actually grab ID and we can print it here so we get only the ID and now uh instead of printing console logging this ID let's put it here so let's do plus ID we could do we can maybe change the backticks it will be prettier so as the dollar and ID and we want to run then because we want to grab the response and do the stuff with it so the response here and with this response we want to do um response we want to transform it to Json so let's say that this will respond with Json we don't have this endpoint yet but it will respond and it will have this post information that we can set to our state here so let's define it here const post info and set post info it will be use State default will be let's say no right and now let's do set post info and we can set post info that we get from here right and now if I refresh nothing works and sorry this should be like this it should be Json then like this okay and by accident I have imported response from Express that I don't need right and now let's see we have uh some kind of errors that because we are trying to get slash post slashed and then ID that we don't have endpoint for so our class client open API let's go to index.js Let's scroll to the bottom and remove the spacing from the this thing and the app dot get and here slash post and then slash and then the ID of the post and then let's do us probably I don't know if we need nothing but I will add it here async and here request response Arrow function like this I will fix spacing and let's maybe respond with Json and the empty object and let's see if this will work looks like it does empty object yes that's that's fine let's print the request the whole request as the Json if I refresh well this didn't work as it should and maybe we shouldn't send all the requests let's send the request params and let's see we get the ID so we know that inside programs we can grab the ID let's grab the ID from request params and now we don't need to respond with Json for now with this ID we want to fetch the post so it's the post and let's do find one can we do find one by IDE let's try if this will work or maybe we can do find maybe it's find by ID yes find by ID and we just pass the ID and this is an async function so let's do a weight and we get post document here at the response from this find by ID and when we have post document we can just do response Json and we can post document send it back to our browser and let's refresh and let's see and we get all the information about our post but here again we get out or as just an ID so instead let's do populate and here I think it should be outdoor so now if I refresh we get outdoor and we get username password we don't want to have username password I want to only have the username no password send box uh let's see author only username and the ID so that is nice so we are sending the post information let's go to post page into our react app and let's say we have both info that we can print now so um let's see um let's say that if we don't have any post info sorry no post info then we will just return empty string and then this will run only if we have post info so um first let's say we want to print an image and the source to this image will be backticks HTTP localhost 4000 slash and then as the dollar and from the post info we want to grab cover yes this worked that's uh that's really nice uh maybe I will put this image into a div with class name image why not I will put it here and this main div I will put also class name so we can style it later post page like this okay under the image we need H1 with the with the title so let's do Post info dot title let's see yeah and then we just need to print the content post info Dot content yes but we don't want to print it like this instead we want to print it as HTML so as the something like this and now um I think it was I think here we need to do dangerously set in HTML and here post info dot content sorry not like this but rather HTML column and as an object like this so this is how it goes if you have um if you want to want to print HTML from a string you need to do an empty div that is closed directly in the same in the opening tag and you set the dangerously set in our HTML to an object that includes underscore underscore HTML to be the string that you want to print and then this way it's printed so let's create another post and let's maybe grab this and I will grab this title I will put it here I will make it capital here let's um maybe I will use this as a summary and I will save this image to my computer I will use it now and now I will put some memory content like this I'll put it here or maybe we can add some spacing like this and do we want to have more spacing yes maybe here and we can probably add some more images so um maybe we can grab this image and we'll copy this one and on the let's say here on the middle no we don't have a button for images or do we no we don't and this should work let's create post yes and we have it so I can open and we have a lot of content here and but now I think we need to do and edit functionality but before we will do edit functionality and let's style this a little bit so first I will go to app CSS and as you remember everything sits into div with class name post page and first I want to style those images to be smaller so we have post page and we have div with class name image the dev class name image and let's make it half of the Max save of 300 pixels that's why it's oh it's still quite big let's see it's this big let's make it a smaller 200 pixel okay so it should end here now let's put the same thing but image inside so EMG should be object fit contain and here we will add overflow hidden okay but this should be more centered so let's start with maybe object position I think it was Center Center and maybe we need to change it over and I think now it's okay let's maybe change to only 100 pixels no it's not Let's uh try to do display Flex okay now it worked so now it's in the middle as you can see and if I make it even smaller let's do 50 pixels and you can see the only the middle of the image is visible but I will make it bigger so we'll have some kind of image here so I can go to home page and now in the middle of this should be the logo so if I click it yeah and this worked and if I click this one we get a lot of more stuff here uh let's see why we have this amount of space in here this is because we have empty paragraphs here um well that's uh that's okay um now I think maybe we can add the also for styling that the the links will look different so let's do div post page and let's do a link and let's do color of um as the 53 but it will remain this text decoration to underline to have this underline yeah and maybe on the post page I will put the header on the top so and it should be centered let's do div post page and the H1 will be text align Center but let's go to post page and this H1 let's put it above the image yes I think that's that looks much better yeah uh sorry I forgot about the time and the outdoor so here let's put the time and here let's do a format ISO this import from date functions and here new date and post info created at as and then underneath under the time I want to have there with class name out or and um let's say it will say bye and then the username so let's do Post info that author that username like this now we need to do a styling for our outer and time let's go back to app CSS post page time as the text align Center Post page time and let's do display and block block yes that's better and here from the H1 maybe we can edit the margins from the top it will be let's say 10 pixels on the sides 0 on the bottom 10 pixels yes and maybe on the bottom only five and now for the time let's make it smaller font size of [Music] um 0.8 Ram and let's make it more grayish or maybe let's make it even smaller 0.7 and let's make it great so let's do a color of I don't know a a yes and now for the outer let's do div post page div outdoor and now let's do a text align Center and margin bottom of 20 pixels let's see yes I think this will be good and I would like to add an A sign at sign so let's see by this author yes and let's make it smaller so let's do font size of uh 0.7 Ram but let's make it bold like this and I think this this looks good so this is how it looks and the mobile it looks good as well and maybe only the home page we need to fix styling for mobiles but yeah let's do this so um for standing here and let's see um div with class name post this is the thing that we need to style as you can see we have two columns 90 and 110 so this one is the right side is 10 bigger than the left side so on mobile I want to put everything under the image so only one column so um how we can do this let's add I will copy this I will comment this out I'll add another one with only one column so one FR and this is how it should look like on mobile and now I will Define a media screen and Main wave let's say this so if the width of the browser is at least 768 then on div post we will do grid template Columns of this so if I make it wide enough it will change to this so that is so that is really nice let's see this is for mobiles and if I make it wide enough it will be like this maybe I can make everything a little bit wider let's say 768 or maybe even wider let's do 800 why not or 960. so it's like this and if I make it smaller it will go like this maybe it could be even like this it should be um two columns that's maybe adjust it I can remove this cone from here and if it's bigger than let's say 600 pixels so now even this size is a mobile mobile mobile and now it's uh now it's big enough to have all the all the space I don't know maybe we can do 700 that way if we make it like this well you can address it yourself right so um now I think we need to also make this image centered so let's scroll down here here we have the image let's maybe do with hundred percent yeah I think that is better now let's see for example on this one yeah the image is nicely stretched um so we have this and let's see here where we have more content uh for the content I would like to have more spacing between the lines so div post page and for all the paragraphs here maybe let's put the rest of the content inside the specific div um let's put here class name of content and now um the content sorry content all the paragraphs inside that's the line behave of the 1.5 frame maybe 1.6 yeah so we have some more more spacing between lines that looks much better right I think the last functionality that we need to build is to be able to edit posts so um if we if I'm logged in as test2 uh and I click this post and enter this post I should be able to click edit button and then see a form similar to this and be able to edit this post so uh how we can do this let's go to post page and here first I need to grab the user info from our context so the const user info from use context from user context and now let's say that under the author I will see if user info that ID or maybe I will just print it yes we have it if user info ID is the same as post info dot post info that author dot underscore ID and then we will put parenthesis here and I'll put a div with a link and it edit this post and let's maybe add the class name of edit so we can style it a little better and here class name of edit edit row why not um and here edit button edit button so let's quickly style it inside app CSS they've added um edit row and text align Center and then now and a tag with edit button class name let's make it look like a button um so let's make let's add background color of I know free for free and the color of white and let's add some padding of the 15 pixels a lot of padding and well I wonder why this this color that didn't work let's see a class we've added button edit post maybe I will refresh padding 15 pixels let me inspect to see here why the styling didn't work edit button okay that's because we get this from the attack on post page we get different stunning so to fix this let's do that let's put the pause page here okay and now let's see the padding the padding is okay only the div here looks a little weird because it doesn't right we need to change this button to display inline block yes and we want to do texture creation to none and the padding let's add the 30 pixels on the sides and let's do rounded corner so border radius of 5 pixels and on this edit row let's add the margin bottom of 20 pixels all right now it would be nice to add a pen icon so I will go to Hero icons and let's search for edit and this will work copy jsx let's go to post page and edit this post I will put here the icon yeah um let's just style it inside our app CSS so Dave or maybe any a tag with SVG icon let's make it have of 20 pixels yeah something like this might be bigger 24 and for this specific button let's make it display to inline Flex yes and let's do online items Center so everything will be centered and let's add a gap of 5 pixels between the icon and the text let's make the maybe the icon a little bit smaller yes and I think this and this should work so now when you click on this button we should go to a specific page like this create post but with an ID so um let's go to post page and now instead of this a tag we want to change it to link instead of graph we want to do two and I will put backticks here so we can put prettier variables and now where do we want to go let's say we will go to edit slash and then ID of the post so post info dot underscore ID link is not defined it hasn't been imported for me let's try to import this uh no let's scroll here let's import it manually link from react router done now it's better if I open edited post it goes to edit slash and then ID now we need to define the page for this uh for this page so let's go to client Source Pages we have create post now we need edit post so edit post dot JS and here export default function edit post and return let's say div we've added post and but we need to add it to our routes objs and let's add a route with capital r route path and the path will go to slash edit slash the idea of the post and then the element will be and it post and we close the route like this and now we have edit pose now the thing is that the form will be actually almost the same as this one so I will just copy it from create post let's see create post and I can copy this state and I can put it to edit post like this and now for the form Let's see we have the I can copy the whole return thing and maybe even the redirect so let's go to edit post we don't need this return I'll get this now for the redirect I'll put this here and redirect and set redirect empty string as default if we have redirect navigate to just slash and we'll have create new post we can change it to update post and that we will I put this function here or maybe Above This redirecting function update post and it will take an event and as well as event prevent default because this is submit on form right what do we miss here modules and formats right so let's grab it from here formats and modules let's put it here see if I remove we should get an image but we don't get it let's see if I remove the formats like this and we refresh modules is here oh I don't know if this changes anything this modules thing um but because we have a lot of copy base here and especially for this react quill um maybe I can put it into a separate separate component so inside source I will create a component called editor.js and here let's do export default default function editor like this and it will just return and the two props that we will need value and on change and here we'll put this react quill let's put it like this value will be value and on change we will run on change and for modules I will put this modules and now for edit post let's use this editor that we created yes and let's put on change equals um that content and the value to be content this way we don't need those modules things and same for a great post inside the create post we have those modules and formats I will get rid of this and here for this react wheel instead of this I will use my newly created editor and the value will be content and the unchanged we will put the set content without parenthesis here and this should work now let's go back to edit URL here and well let's see now it's everything is set to better edit post we are back here let's see editor and do I need to provide maybe I forgot theme to be snow no this doesn't change anything we have a module so B should be modules let's see now we have images and more stuff right and so this uh this now works it's better but back to edit post now uh when we enter this page edit post we want to grab the ID from params so it's the const ID from use params and these params is from react router Dom we can get rid of react quill from here because we use editor here component instead but now let's use and use effect and no and the dependencies here and here we want to do fetch we want to fetch information from for this specific post so let's do HTTP localhost 4000 slash and now the uh now post and now the ID of the post that's the plus ID then and then we get the response [Music] as the arrow function here with this response we want to run Json on this to parse it to Json then we get post info here that we can let's do Arrow function Here and Now from this post info we can fill uh all those informations so let's do a set title and here we can do Post info title and Set uh content post info content and set summary post info summary and then that's it I guess right and well we could display the image if we if we want to but that is not that important let's say we will update the image only if we want to um we will pick the image if we only if we want to update the image or maybe we should display it so let's add here another state for the and cover set cover use State default will be empty string um do we need it to display the image maybe we don't right but let me know in the comments if if you want me to to add it so I can show you right but we have all the information but now instead of this create post button we should have update post all right and now this update post what this function should do it should do a fetch request to http localhost 4000 and slash post but this time is it will be a method a method of put all right and um we need to grab all the information from State and create a form data from it so as the const data equals new form data and the same way we did for create post so I will grab all this and the files can be actually empty the files can be an empty string so I will do question mark and Dot here in case this is not an array of files and now let's see maybe here even I can check if uh if we have files of zero if we have files of zero then we will add a file to the data and then we run put for the body of the request will be this date form data that we created and and let's do a weight here and we need to add async here right and that way we know if this has been updated and after we updated we want to maybe set redirect to true and let's see set redirect to True let's say it will be false here by default and now if we have redirect we will not redirect to the home page but instead to slash post let's see what should be the name of it slash post slash the ID so the plus and then the ID that we get from the params so if I click here if I update the post then it will redirect me to the post that I have updated but first we don't have this put endpoint for slash post so let's go to API index.js and let's see here we have for creating new posts so when we post to post then we need to add another one when we put to the post so let's do up put to slash post then let's make it a secure request response because we will need some async functions here and first we want to check if we have any file first so if we have request file and but before we can check it we need to check in we need to add this middleware here so let's put it here sorry I got like this and maybe first let's respond with Json to see how how this works response Json request file like this and to see if we send something and let's go to edit post let's remove this redirection let's click update post and let's see what we get here and no preview maybe because we need to grab the response first and if response okay and then we will do set redirect to True like this as the update post let's see 200 it was a put request with a lot of payload file it to lower the response data no data found for resource okay let's see um if we let's file is this let's try again update looks like it's uh empty but I'll post also test to before and this update post okay now it sends only test four so it looks like that file is empty but if I try to update it let's see I'll put this thing and now update let's see file is and we get this information right so we can check that if we have request file um then we want to do all the stuff here with the files so I will copy this here maybe we could put it as a as a function so there will be no copy based but you can reformat this function yourself right if we have request file then we will rename it and then let's say maybe here let new file equals um or maybe here we have this New Path maybe we can Define it here New Path equals empty or maybe let it equal new and here we'll update this new path to be this and this way here later on where we we where we are going to update the post we can check if we have a new path to the file all right but first before we change the check the post we need to send the cookie so let's go back to edit post and we need to include credentials include yes and now uh we can grab the cookie so it's the const um I think it was token token from a request and cookie cookies let's see token from request cookies then let's maybe just copy all of this and let's see but here we were creating new post post crate and let's see we are verifying the cookie and then if we get an error we just wrote this error but where if we get the information we need to check that information ID so the user ID from the token is the same that we get from the um is the same as the outer of this so how we can check it we first need to grab the post so let's grab the post comes post doc I will comment and the rest for now let's grab it so let's do a weight post find by ID and we need to grab the we need to grab the post ID that we don't have here let's go back to edit post and let's see let's send it data set ID and let's send let's send it as ID bank here and we can grab it from here from request body and let's move it here so we have the ID here so we have now that I post doc and now we can check that the user ID that is here is the same that is here so if that post doc outdoor is different than the maybe we can just compare it here and let's just do console log or maybe let's put it as a constant is outer equals post doc author is the same as info dot ID is sorry is outer here and then let's do response Json is outdoor okay and we don't need this now let's see if I hit update we get 200 is outer is false so looks like I'm not the author of this but I want to check post doc author um stock and let me check also info update so inside info I am the ID of 8e postdoc author 8e so those values are actually the same the problem is that those are the same when we do when we run Json of them but before we do this author is actually type of object ID and to do a better comparison we need to do Json stringify on all the on those two to have better comparison so let's do stringify on the second if ID and now if I hit update post let's see his author is true because info idea of the user is 8e and post doc author is also 8e so um now I know that it's the correct author so if number if not correct author I will throw an error here invalid outer or maybe I can do um Pro um you are not the outer and I can also hear the response status 400 and Json with the same text you are not the author yeah something like this here later we know that we are an auto maybe we can skip this row and I can just return here right but if we are an outdoor what do we want to do we want to update this post document so it's the post document and we want to update it and we can update just like this and we need to add a weight because it's an async but before we update and we want to also put all the information like title all the information from the request body so title summary in case it's different content and well I think it's all but now I'll put it inside different lines it will be easier to read but now with the file as you can see and we didn't update the file or the cover as it's called in the database but we should update only if we have any new path so if New Path then New Path um like this but otherwise we don't have New Path let's build the same thing that we had before as the post doc dot cover all right and now let's see um I will refresh so we don't have any file here and let's do it let's put two here and I can get rid of all of this let's just respawn Json with the post doc all right and now I will update post and looks like everything worked let's go to edit post let's uncomment this set redirect update post and we have this two here and it as you can see it's open the cover photo is open and box I can pick a different file with the closed box update box update post and now it's closed and let's maybe check if we can add some images so I will pick here the open box but um here maybe in the middle I will put an image of I cannot pick web P images okay I just made it jpeg so now it should work yes now it works yeah so now we can even include some images I can even make it bigger so I will I will remove this oh sorry it's not here I should click first edit remove this and here let's add large version let's put it update post and now we have even the large version so let's see we can create both we can edit posts we can even add images in between we can create users we can log in log out [Music] um two more things I would like to fix first is that for this logout I would like to have an hand icon so app CSS and maybe for all a tags let's do cursor pointer so this should work on the logout yes it does and also for I think we have for all the buttons same thing cursor should be pointer right um another thing is I would like to have like a hello and username on the header so let's do header and if we have username let's add a span here and well let's say hello and then username user name yes uh that I think that looks my better maybe we don't need this but that's a cool thing to have all right so that's all for today I hope you enjoyed the video if you did please click the like button and subscribe if you want to see more videos like this one have a nice day and see you in the next video
Info
Channel: Coding With Dawid
Views: 103,913
Rating: undefined out of 5
Keywords: mern stack, mern stack project, mern stack tutorial, mern project, mern blog project, mern, mongo express react node project, mern project tutorial, mern blog project tutorial, mern project for resume, mern stack project tutorial, mern stack blog project, mern stack blog app, mern tutorial, mern stack app, blog app, javascript, fullstack javascript, fullstack javascript project, fullstack javascript blog tutorial, node, express, react, mongodb
Id: xKs2IZZya7c
Channel Id: undefined
Length: 212min 9sec (12729 seconds)
Published: Sat Jan 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.