 Hey, what is going on everybody? My name is Raddy and you're watching my channel, RaddyTheBrand. Today, I'm gonna attempt to build a very simple recipe website using Node.js and MongoDB. Now, let me show you the project. So today, we're gonna be building this layout using Bootstrap. I'm gonna show you how to render different pages, a simple search bar. We can look at how to do different queries such as the latest recipes, show random recipes. We're gonna have different categories and different recipes. Of course, the recipes will have detailed views. So if I click on this one, this will come up with the detailed view. If we search for something, that would also work and so on. And the last thing that I'm gonna show you is the publish your recipe bit, which is we're gonna build a very simple form that will allow you to submit a recipe with a basic image. And that recipe will be shown on the front, depending on which category you choose. And that's pretty much it. And there is a lot of things that I could have done, but I tried to keep it quite simple. If this is something that you would like to build, stick around, consider liking the video, subscribe to my channel for more videos like this and comment below for the algorithm. Hello and welcome everybody and let's get started with this video. The first thing I'm going to do is create a new project folder. I'm going to call this a cooking blog and let's enter the folder and let's initialize a new project. I'm using Windows, so I can do left shift, right click, open PowerShell window here. And this is basically going to CD to my project folder. But if you're Mac or Linux, all you have to do is use the CD command and the folder that you want to enter. Or if you want to go backwards, you put three dots and so on. Anyways, to initialize a new project, we need to do MPM in it. And I'm going to put the dash wife like, which will skip all the questions. So it's going to set everything to default, such as the name, the version description and so on. And the first thing that I want to do now is install all of the dependencies that we need for this project. So let's start by doing MPM, I is short for install. And then we can list all the dependencies that we need. So we're going to start with connect flash. Then we're going to have the cookie parser. We're going to have we're going to have dot ENV. We're going to have EJS. We're going to have express express EJS layouts. Express for upload express sessions and MongoDB. And the last one is Mongoose. Don't worry, I will be explaining every single dependency that we're going to be using as we go along. This should take a couple of seconds. Okay. And now we're done. We can open our project in our favorite code editor and I can just do code dot. And this should open the project in Visual Studio Code for me. Here it is. And as you can see, the project is open here on the left side. I've zoomed in a little bit so you can see a little bit better. And also if you're using another code editor or even Visual Studio Code, you can just go to file and just open your project folder from here as well. Now that we have everything inside here, if we click on package dot adjacent, you will see everything that we just created, the dependencies here. And we also want to add node one. So every time we'll make a change to a project, we don't want to stop the server and restart it manually. So let's do that. Let's go back to the PowerShell, in my case, MSDNPM, install node one and then dash dash save dash def as this is a development dependency. This should take a second and if we go back to package dot adjacent, you will see that the dependency has been installed here and note that the versions of all those dependencies might change in future, they probably will do and so things might be slightly different if you're watching this video in future, just have that in mind. You're just going to have to Google the errors that you're getting and so on. Anyways, if you want our project to run with not one, we need to go and the scripts here and add a new line. So I'm going to do comma and the line will be start column and then inside here, we want to start our application with not one and then our application file will be called app.js, which we're going to create now. So let's save this. And we're pretty much done with this file. So we can close it and we can start by creating or app.js file. So inside here, I can just create a new file called app.js. And this is going to be kind of like the brain of our application. So we're going to include all of the dependencies here and like middleware and we're going to create an express server to do this. Let's start by including only the dependencies that we need now. What I'm going to try to do is add the dependencies as well. We need them. So it makes a lot more sense. So everything will be hopefully sectioned in this video. So you can skip to it and hopefully it will just work. Let's try that. So first of all, we need to require express. So we're going to do const express equals require and then we require express so then we need the express layouts const express layouts equals require and then we require express ejs layouts like so. And the layout will be basically very helpful when we create or template for our website where we'll be using bootstrap. But what this allows us to do is create different layouts for different scenarios so we don't have a duplicated code. I will show you in a second how this works. And now we need to initialize a new express application to do this. We can do const app equals express close this. We need to set a port number const port equals we can set an environment port number as well if you wish to if you wish to upload this project somewhere. So you might want to do this process dot e nv and then port number. But because we are working on localhost, I'm just going to say one manually. So we're going to do all port 3000 like so. We need to also require dot e nv. This is going to be for storing or database details. So we might as well do that now to require dot e nv is a little bit different. I have made a full on video on this. If you want to check it out, it will be in the description below for remember to add it and let's put dot e nv is definitely in my Node.js playlist. If you want to check it out and then we need to do config like so. Now we need to add a couple of middle ways here. And the first one is the express euro coded. And this will basically allow us to pass euro encoded bodies. So let's do that super quickly. We can do app dot use and then express dot euro encoded. And inside here, we just need to pass one option and that option is called extended and then true like this and close. Then we need to set up a static folder and I will and I will explain. So app dot use express dot static and or static folder. I'm just going to call public now. What this is going to do is every time we require something to our HTML such as images, scripts, style sheet or whatever. We don't want to kind of like go like we don't want to list the full path. We just want to put, for example, slash image slash images folder and slash image dot JPEG. That would be a lot better than listing the whole folder. And that's why we're creating this public folder, which will create in a second as well as soon as we finish this. We also need another middle where which is for the express layouts. So let's do use express layout and for the layouts. We need to set a main folder. So we're going to do app dot set and this will be loud. It's going to make a lot of sense in seconds. So the layout folder that I'm going to use is going to be called dot layouts. And then main. All right. This is where we're going to store our layout and our main layout is going to be just called main. Then we're going to have to create some routes and we might as well start building or folders and everything. So let's do const routes and equals require. And we need to require all routes which we haven't yet created. So this will be server slash slash routes. And then let's call a recipe, recipe routes.js. And we want all app to use those routes. So we're going to do app.use and then slash and then routes like so. That's all good. And the last thing that we need to do is to make sure that all app is listening on this port number. So let's do app dot listen and then port number. We need to pass the port number from here, which is going to be the port 3000. And then we can do a narrow function inside here and just console log something. And I'm going to console lock with the back takes single back takes. I'm going to console lock listening to to port and with the dollar sign curly bracket open and close. We can pass the port number from here. Okay. This is all good. Now application won't work just yet. I'm thinking let's create all the files that we need. So let's start with the public folder. So so public folder. As I said, we're setting it here and our public folder is going to have a couple of things. It's going to hold all styles. So CSS it's going to hold or images. I'm going to shorten this to IMG and it's going to hold or front end JavaScript and potentially will probably hold the uploads as well uploads here and that's it will create the files in a second. The next thing that we probably want to do is or server folder which will have let's have a look. This will have server folder and inside the server folder we're going to have controllers. Controllers is where we're going to do all the queries and control the the functionalities of every single page models. Models are going to be the way we structure or database and it will make sense in a second as well. And lastly in here we're going to have routes which we're going to have to create very shortly and also let's create or views folder now. So the views folder is going to be where we store all of our HTML pretty much. Obviously in this case we use an EJS but this is where we're going to store all of our EJS files. So all of our pages and as I said earlier we're going to have one main layout which is going to be in this layouts folder and then it's going to use main dot EJS. So let's create that. So I'm going to create a new folder inside here called layouts and inside this folder we're going to create the file called main dot JS. Okay cool. So let's do so this is all good. Save it. Save it. Let's do a very simple route just to test whether this is working in order to do this. Let's go to routes. Let's create our first route which is recipe routes. So recipe routes dot JS and inside here we're going to have to include express again so we can use the router const express and then we require express like so and then we do const router and then this will be equals express dot router like so. Okay we should be able to now use the router and we also want to bring the controllers which I'm going to create now in fact let's create a now so I'm going to create a new file called recipe controller like so and this is going to be a JS file. Save this go back to the recipe route and let's include a file const recipe controller equals require and then we require the recipe controller which will be backwards once controllers slash recipe controller like so we don't have to specify dot JS in here and we can just close and now in order to be able to use the routes we're going to actually have to export this so we're going to have to do module dot exports and we export the router. Okay at this point we should be able to create a very simple router and we might as well make a comment in here so let's do slash and two asterisks and inside here I'm going to say app routes so this is where we're going to list all of our pages and they're going to be linked to the recipe controller so let's create one just to test the application I'm going to use router and then the first one is going to be get so get and then we just want to get the home page like so just slash and that would be and now we need to use the controller so recipe controller and let's name the first one home page is just so the description is make sense so let's do your home page home page like so and close obviously we need to create this controller now so we can close this close app.js as well and we can jump into recipe controller which is in server controller specific controller and we can create or first route and test the page now to do this let's make a little comment here so slash and just so we start to well so let's do this is going to be a get page and it's going to get slash so this is going to be a home page and on the second line let's just say what page are we getting and this is going to be the home page home page like so and that's it so in order to use this we're going to have to do exports dot and then home page home page is what we just created in the recipe router and this is going to be an asynchronous function and then we're going to have require sorry request and response and then this is going to be another function like so and inside here is where our logic is going to go for every single page obviously we're going to have different controllers so just to test this let's render the home page which we haven't yet created so let's do that so let's do press the render and we want to render the index page now we haven't yet created this but I'm going to show you how this works in a second and actually that's it so first of all we want to render the index page which we haven't yet created so let's go into views and make sure that the main dot JS is actually called main dot EJS because we're using EJS my fault and let's put this into layers this is going to be or main art actually it is already there and inside views I'm going to create or first page which is or index page or home page you can call it whatever you like I'm going to keep us index dot EJS and this is going to be a home page and this is going to be our main layout now let me show you how this works the first of all in main dot EJS we're going to have to create like a global layout so let's do a quick HTML I'm going to show you how this works so this is a very basic HTML and we want to put everything else this is going to be a layer that we can reuse and we want to put all the other pages to be using this layout so in order to do this we can use EJS so we're going to do a start EJS like so dash and then body and then dash and close EJS like so and hopefully if we put something in the index page now let's put each one of hello world and safe right everything is looking good save everything and let's have a look at what we get now first of all we need to actually start the application and let's hope that we've done everything correctly so it's going to be MPM start and press enter if you see node months starting node month with green and listening on port 3000 that's all good and now if you open the browser okay and we're getting an error error note the foot engine was specified and and this is because I actually forgot to specify the view engine so if you go back to so if you go back to app.js we can just specify the view engine inside here we can just do app.set and then view engine like so and the view engine that we're using is EJS and we're done all right let's save this restart the server if you have to as you can see it's restarted automatically and now if we go to the browser and we put localhost with 3000 you'll see that we're getting hello well now the interesting bit is that if I was to inspect the code I'm going to do control and you and if I was to inspect the code you will see that it's using the main template so this is coming from the main template and this is the actual homepage which is really good so we'll be able to include all of our style sheets in here and JavaScript stuff and just and you'll make creating pages very easy for us and you'll be very easy to maintain right let's close this and let's go back so that's all good. Let's close this let's start building or main template alright so we're going to be using a lot of bootstrapping here and I'm thinking let's start from top to bottom and we'll work our way in so first of all let's have a look at the title now what we want to do is potentially we want to have because we're using a template and this is going to be reused on every single page we don't want the title to be the same so we either want to pass title from our controller or we want to have a default one and in order to do this let me make some space a little bit and I'll tidy it up in a second so inside here what we can do is we can do a little bit of ejs so let's start ejs like so and close it like so and inside here we can do that needs to be equal by the way and inside here we can do type of title title is the object that we want to pass not equal undefined so if the title is not undefined we want to pass the we want to grab what the title is but if it isn't defined if we don't have one we want to set a default one so I'm going to put title to be with column to be equal something like cooking block dash made with node.js something like this and hopefully now if I was to tidy this up a little bit hopefully now we won't get any errors or anything like that and if I was to refresh this I don't know if you'll be able to see but if I was to refresh this it says cooking block made with node.js let me zoom in and but if we wanted to pass a custom one so what we have to do is we have to go back to a controller and where the rest render is we can actually pass objects from here so for example I could do something like inside curly brackets comma and then curly brackets is where we pass objects so I could do something like title and then just provide a title from here let's just say homepage one now so let's have a look so it's not going to use the default now anymore if I refresh is going to say home page and this is how we pass the title and then if I refresh this you'll see that it says homepage so let me change these to something like okay it doesn't really matter too much obviously make sure that you'll see it's a little bit more SEO friendly I guess but that's just an example I remove the taskbar so we have a little bit more space and now that we have the title out the way let's have a look at setting up bootstrap so we're done with the title and inside here we want to include bootstrap so let's go to the bootstrap website so if we search for bootstrap the first one here at the moment we're currently in version 5.1.1 I'm not going to do anything crazy with bootstrap I'm just going to use it to quickly bootstrap the layout so if we click get started I'm going to use the CDN from here so I'm going to copy this and go back and paste this into here into the header into the head of our website here I also might want to grab the icons but before we do this let me quickly grab the JS just in case somebody needs I'm just going to do the bundle one so this needs to be put at the bottom so let's copy this and let's walk here at the bottom and that would do and then I want the icons so for the icons let's have a look for the icons I think we have to go under icons and then where is it? Learn more about bootstrap icons let's click on that you can MPM install it but I'm just going to use it from a CDN so let's have a look install here we go here we go this is what I want so there are two ways of doing it we can either use the link or we can import it into your star sheet I'm going to use the link for now let's copy this paste it inside here I also want to grab a font so I'm going to go to Google Fonts quickly and let's find the font Rubik and this is the one that I want so I'm going to click on it and I only want the 3000 so this one here select and I want potentially the 5000 so let's select that and the two ways of including this as well with a link or you can import it into straight into your star sheet I'm going to do the link for now so let's copy this and paste it inside here and the last thing that I'm going to do here in the head is include my own star sheet because I will do like a very little CSS just to make the layout a little bit better so to do this we can do a link and then we can just link star sheet so link rail star sheet href and then we can put slash CSS I think it is and then styles I'm going to put styles with s dot CSS then we need to create this file and this is what I was talking about earlier with the public if you do app.js this is where we set or public folder static folder sorry which is public and that's why I'm able to just go straight away into the public folder by doing slash CSS so CSS and then we just need to create this file so I'm going to do styles dot CSS and save right in order to test this we can definitely do something like a background color sorry body and then let's do a background color of black and save so if we saved all this hopefully we should be able to see the changes if we go back refresh as you can see the background font is now black and you might have noticed that the font has changed is coming from bootstrap and that's why it's slightly different okay this is pretty good so far we can now start working on all out so if you go back and let's remove the style here we won't need this but now and we don't need this for now so all we have to concentrate is on our main dot ejs file here and let's build it up so hopefully you won't be too much let's start first of all I want to have my website centerline so I'm going to wrap everything in a container so let's start with creating a div with the class name of container XXL I think this is the big container that you can use from bootstrap we're going to have padding on the X axis middle and then five background I'm going to set to white and I'm going to put shadow to large okay that's all good so this is our container everything is going to be going inside this container and so I can add the body in here but the body I want to wrap inside a main tag so I can do main this is an HTML five tag and I'm going to wrap it like so think this is going to be good and also I'm going to need some sort of a header and a footer so what I actually originally what I've done is actually search for bootstrap five templates and if you click on this link here which is get bootstrap dot com docs are five point zero examples you will see a lot of examples in here so what I've done originally is I actually copied one of them I think it was maybe this one and I modified it a little bit but yeah if you wanted to do that to save a little of time I mean to fair this one looks pretty nice actually but I'll just leave I'll just build my own one but if you wanted to do that you can literally inspect this copy the code from here so you probably just do right click edit HTML and just control and a to grab everything copy and paste it inside here so if I was to paste it just to show you then let's have a look then you'll see oops it's a little bit zoomed in but you'll see that everything is in a container and we have our header here with our home page just says hello world but as you can see this is working I'm going to build my own one just because I want to slightly different but I should it shouldn't take too long so first of all I'm going to need to include my images by the way so let's go to the images folder and reveal in file explorer at the moment is empty so let me grab some some of the images that's going to include my logo and so on all right so let me tell you what's happening so in here I'm including my logo I have created a background color I have a hero image and another image with their publishing recipe section and these are just for the categories so just so we have something to use that's all so what I'm going to do is start building the header now close this close close and let's build the head I don't really want to over explain every single class name because there is a lot of them but I'll try maybe I can do it initially and then I can speed up the process to not explain anything else because I don't want this to turn into a bootstrap tutorial so this is going to be a header and that's going to have a lot of class names we're going to start with the flex because we want this to be a flex container flex wrap wrap align items center justify content center content middle point between padding to the y axis of free margin bottom of four for the bottom we want and then inside here I'm going to add the first one which is going to be a link and that's going to be my logo so I'm going to do a href then I'm going to put slash because I want my logo when we click on the logo I wanted to go to the homepage and then I'm going to put a class name whoops class name is equals and then this is going to be the flex and then align item center that's correct and then call and the free margin bottom to margin bottom middle screen of zero text dark and text decoration none because I don't want the link to be underlined and inside here I'm going to use my image so I'm going to do image and then source the source will be slash images slash logo and that's an SVG file and then I'm going to put a width of two to nine which already know as I was saving the SVG and that's the height is 68 that's sometimes important. So your images don't blink and all I'm going to put something like cooking blog made with node.js and close this. This is all logo done and now I'm going to create the menu inside here. So this is going to be an ordered list. This an order list is going to have a lot of classes is going to be enough with a call of 12 call middle also much bottom to justify content center and a margin bottom margin sorry middle of zero and then inside here obviously we can have all links they're going to be inside a list. So let's create a link href and this one I don't know these are just for show to be honest but this one is going to be let's say the home one and I'm going to have a class name of nav link padding to the XY X axis of two and then link secondary like so secondary killer and then this is going to be the home maybe let's did I close the link? Yeah. Okay. Hopefully now we should be able to just duplicate this a couple of times. So let's have home about submit and contact home about submit. I'll probably won't even end up making all those pages. They're just for sure to be honest but you will see how to make pages it will be very easy. So let's just link them anyway. So about and then this will be submit recipe recipe and this could be contact like so and the last thing that I want to do is add a search bar. It's not going to be pretty. I'm not going to add a button. I'm just going to do it. One of them that when you press enter it submits where you can add a button if you wish to store it to you. So we're going to do a deal with the class name of co dash middle dash three and then text dash and inside here we're going to create our form. So this form is going to be it's going to have an action of search. So we want when we submit this form to go to search but don't worry I'll come back to this one when build the search as well and then the method is quite important method. Let's put it as post because we want to post data to the search page. But yeah as I said I'll come back to this and we just want an input here. So I'm going to do input with the type of search and then this is going to have a name and the name is quite important. This is how we're going to pass the data. So I'm going to just make it very kind of like obvious search them and then let's put a class name of form control and then place holder is going to be equals search dot dot dot and then area area label label is going to be equals search for accessibility and that's it. Okay. I think this is good here. We have the header will test it in a second. I'm going to do a very basic photo as well. So inside here let's do a photo and for the photo I'm just going to do a paragraph and I'm going to say build by ready which is myself and let's just put a little bit of padding so class padding why the y axis of five. So this is up and down and I think I'm pretty happy with this as long as it works of course. Yeah it's all looking quite nice and hopefully we won't have to mess with this page much more. So if we save this go back to our website. Let's refresh it and let's have a look. We're getting the logo we're getting the menu here and a search bar without the button we just press and turn this. Now the first thing that I noticed is that the container here it's a little bit small for my liking so I definitely want to reset that and I want to make this a little bit better looking. So I'm going to add a background to this and yeah customize ever so slightly. So let's do that super quickly. So I'm going to go to my public folder CSS style dot CSS and let's write a few styles and we'll come back to this as well when we add more. So what I'm going to do is first of all we want to change the font to the one that we added from Google. I believe it's called Rubik. Yeah here it is Rubik. So we want to add that and in order to do that I'm going to reset the bootstrap one. So to do this we can do column route and then we can do the bootstrap font sans serif and then this is going to be set to Rubik and Rubik is this yep Rubik and then this is going to be sans serif like so hopefully this should reset the font now if I refresh this change here we go. The fonts have changed the topography has changed which is good. Now I want to make the container a little bit larger than this. It looks pretty small. So I'm going to do container dash XXL and I'm just going to reset the max with this. So I'm going to max width of one five three zero pixels. Save this go back refresh and as you can see we have a bigger layout now which I think that it looks a little bit better. It's still going to be fully responsive and everything. So don't worry and let's add a little bit of flair to a website. So I'm going to do a body and I'm going to do a background image of URL and then inside here whoops inside here with double quotes we can do image and then slash I like food dot SVG. I downloaded this SVG from somewhere and slightly modified it to make it look nice but I'll I'll definitely link everything in my blog post or in the description below and then as I need to give credit obviously to the author of the image and then the background color I'm going to change. I'm going to change to something like RGB. Oops. I definitely don't want this. No don't do this. The RGB. Damn it. That's the RGB is going to be two four three two four three two four three two four three. Okay. This is a very grayish color as you can see here and then let's have a look at what we get refresh. We get this really nice background color which is pretty cool and one thing that I would want to do is reset all the links. We won't be able to see them now but the bootstrap links are usually blue. So I'm just going to do that now. Just reset them. I don't want them to be blue. So I'm going to hack this super quickly color. It's going to be set to well and then this is going to be BS dark I believe. Yep. And that's absolutely fine. We're not getting any errors. It's a good if I do. Okay. That's pretty good for all main layout. And now we can actually start building our home page where it says hello. Well, okay. Let's start building the home page now. And in order to do this let me close everything by the way. I'm going to open the stash. I'm going to have the starsheets.css open just because we'll probably end up writing a few stars but we are now pretty much done with the main layout. So let's close that as well. And let's jump into our home page which is in views index dot e j s. So inside here we're going to have to build a few things. Let's make it pretty first of all and then we'll keep populated with data and so on. Let's start by building like kind of like the hero image and I've already prepared the an image with this and I'm going to show you how I've done it as well. So I'm going to do a deep with a class name of row. So on your row and inside here I'm going to do flex large row reverse align items center gap five padding y four in margin bottom or four inside here we're going to have another column. So this is going to be a deep with the class name of coal dash 12 and coal dash large six. So on mobile we want the column to be full with 12 to take 12 columns and on large screens I wanted to be taking half of the space so six columns and then inside here is where we got our hero image. So let's do an image with the source and the source will be image and then hero dash image image dot PNG and then this is going to have a width of me close this. So okay this is going to have a width of 607 a height of 510. What else do you need a class name of the block MX LA LG auto image fluid to make it responsive. Now we can put load in lazy as well. Of course we'll probably need an old text is also cooking with no jazz will do for now and then we need another column. So let's do another diff with the class name of coal dash 12 and this is going to be the same as above large six six excuse me and inside here is where we're going to have all hero text. So I'm going to do an h1 here and I'm going to say let's say class name display dash five font weight bold and imagine bottom three and for this I'm going to put huge selection of delicious recipe ideas ideas like so and then I'm going to add a little bit of text is also let me tidy this up. The text will be in a paragraph and I'm actually going to copy this because it's quite long. But first of all, let's put a class name of late and you can pause the video if you wish to copy it. But of course you probably have your own one. I assume this is going to be explore or huge selection of delicious recipe ideas including easy desserts, delicious vegan, vegetarian dinner ideas, gorgeous pasta recipes, quick bakes, family friendly meals and gluten free recipes. That's pretty cool. We also want to buttons and underneath this. So I'm going to create another deep inside here. So deep with the class name of the grid display grid gap to the and the flex and then justify and the start like so. This is going to hold all two buttons. So a href they're going to be links. So href this one is going to be maybe like explore latest recipes. Explore latest and this is going to have a class name of PTN PTN primary PTN dark PTN large and then fighting on the X axis of four and me the MD two. All right. That's so long. Explore latest and now I can actually copy this one and just modify and this one is going to be maybe we can do a random recipe from the database and the recipe BTN BTM outline is that I think and then this is going to be secondary and then BTN large and yeah, that can stay the same and we just need to change this into show random. Okay. Let's have a look at how this looks like first of all. So let's refresh and as you can see, it's looking. All right. If you want me to show you how I've done this, I actually use the blob maker website. So if you go to blob maker dot app, this application, this website creates different blobs. So I just kind of like generated one that I liked and then I put this blob into Photoshop and just master with an image from unsplash.com that will be linked will be created in the description as well. And then I kind of like turn the blob around and just paint it with different colors. I can probably show you in Photoshop in a second. Here it is. So that's how I've done it. Here is the image is masked as you can see. So and we have two more blobs on the outside and I'm not too sure whether I'm going to include these files yet, but yeah, I might include them on my blog so you can download them and insert your own image and I've done the image exactly the same here. I've put three blobs and just smashed a few images from unsplash.com. And I think that it turned out alright to be fair and just exported it as a PNG. The next section would be the categories. For now, let's make sure that all out is working nicely. And then we're going to obviously populate it with real data from a database. So let's do that next. And that's going to be a totally different section. So I'm thinking let's do it here underneath and I'm going to comment this just so it's a little bit clear. And this is going to be the categories category start. Let's create another one categories. And okay, it's out here. We're going to create a div with the class name of row, row calls to row calls dash large six and then G to G large three and P Y four. I'm not going to be overexplaining the class names anymore. As I've already probably explained most of them. And then inside here is where we're going to have the categories as links. So inside here, we're just going to create a couple of links. So let's start with a href and this potentially and we'll have to set up the link later for this. So let's leave it like that. And let's put a few classes call text center and then category which is a custom one underscore underscore link is going to be a custom class that we're going to create. Usually you could have category as your main class in here, but I probably won't use it. So I'm just going to do category link like that. I close it and inside here we're going to have an image and a title for the image because we want to kind of like must get kind of like have it as object fit. So you always fit fits the card. I'm going to do a div with the class name of category underscore underscore image. Oops underscore underscore image and then shadow like so on inside here is where our image is going to be. So let's do image with the source of image and then we can put a category image for now. Let's grab one. Let's go to images and let's just grab the first one here. So American food. Let's do that. Let's close it. So we have American food with the old tag of feed. Let's do that. Let's have a lazy loaded lazy potentially. I'm not going to put within height on this one. But because we're going to have it as object fit, we'll see how this works. And then the last thing I want to do is kind of like add a title for each card. So I'm going to do a div with the class of PT dash one. Now I'm actually wondering whether this and I'm just going to put American food. And I'm wondering whether this needs to be kind of like H2 or something but it's inside the link. So let's leave as it is. Okay though. So this is going to be our card. We're going to have I think five of them maybe. So maybe we can just duplicate this five times or one, two, three, four, five. Let's have a look how this looks like. Okay. Obviously it looks ugly at the moment, but we can style this now. Alright, we can use the category image and the where is the other one and the category link to style this. So if you go back to styles, let's have a look at how we can do that. First of all, let's start with the category. Let's let's do a little comment. Category card, whatever. Okay. And inside here, let's start with the category link. So category this is a class name of category link. And I can do text align center probably already done that actually with bootstrap. I want to display as block. I want the text declaration to be none. If we have any links and let's do let's do a hover effect, a simple one transition. Let's do our five 250 milliseconds. Oh, let's do a little hover effect. Yes, our category link and then hover. And I'm just going to scale it. So I trans that is transform is them transform scale of 1.1 close this for the next bit. Let's do the image now. So the image would be category underscore underscore image. And then what I'm going to do is display this as flex. I'm going to justify the content to be center. Align items center height. Let's put as 100 pixels margin bottom is going to be 10 pixels. Let's put a little bit of a box shadow around. So this is going to be zero pixels, three pixels, six pixels. And I'm going to put RG RGB a of 0.0.0. And then point, sorry, point 16. I think that should work. And then overflow needs to be set to none. We don't want the sorry to hit him. We don't want the card images to overflow. And then I'm going to put a border radius of eight pixels for the corners. Lastly, we want to make sure that or image inside kind of fits all the time. So we're going to do dot category image. And then we select the actual image inside. And then we can do with 100% all the time. And we want object fit to be set to save this and hope for the best refresh. And as you can see, this is looking pretty nice. Obviously, this is going to change from the database. And actually want to change this manually. Okay, that's pretty cool. Let's change this one to say view all. I've prepared an image for this. So let me go back and go to index dot EJS. So this one I'm going to change. Let's say so the image is going to be called view or dot JPEG, I think I'm going to change the odd tag to be a view or view all categories loading lazy, that's fine. And then this is going to be saying view all and the link, the link could be potentially categories. I haven't yet decided on these categories. I think that would make sense. So if we save this refresh, we have kind of like a view button, I've kind of cheated and Photoshoped three dots in here. But yeah, you can make it a little bit better. So this is all good. I think if we do the next section, which is going to be kind of like the actual recipes, we're going to have different section like latest American Thai Indian and so on. So maybe if we do that, then we can look into doing the database stuff very shortly. Okay, let's look into the next section, which will be the latest recipes. And once we build the CSS for that, well, it's not going to be much CSS. But once we build the section for that, hopefully the rest will be easy to duplicate. And so let me tidy this up. Let's have a look. So categories and I'm going to copy this and I'm going to say latest. I just put latest start and then latest and like so. And inside here is where we're going to put the latest recipes. Now for this, I'm going to create a section here. So let's do did I create a section for this? I mean, yeah, this could be could have been a section. It doesn't matter too much for now. Okay, this could be a section. And then this section is going to have a class of padding, bottom for padding top four. And I could have used the padding, I could have used the other one. And then we can do a diff with the class name of D display flex margin bottom of to align items center. And then inside here, we're going to have a title. So with h2, I'm going to put latest recipes, latest recipes like so. And we're going to have a link on the other side. So this is going to be href with the link of probably explore latest. Let's leave it like this. Class name will be MS auto to push here on the other side. So this is going to be or view more button like so. And then underneath here is where we're going to have every single recipe, like the cards. So let's do a diff with the class name of row, and then row calls to a row calls large five and then g2 g large three. Okay, not too bad. Now inside here, we're going to have very similar to the top. We're going to have a link for the card for href. And this is going to go to recipe. And then we'll probably have an ID in here, which will add later. And so don't worry about this at the moment. And then this is going to be a class name of co and then text center. And then we're going to reuse the category link class. Like so close this and inside here again, to be fair, we could just copy this. I think let's have a look. Yeah, we could just copy this. I think so let's copy that and change this one to something else. We grab a recipe. Okay, let's put this one here. I'm going to put the image of this one here. And let's put the name of, okay, chocolate but no fee. I'm gonna copy this, put it as a no text. It doesn't really matter at this point, to be completely honest with you. That's absolutely fine. But one thing that I'm not going to like now is that if I was to refresh the latest recipe image is going to be exactly the same size as this, which I don't want. So I'm going to do a quick modify for this to make the image a lot bigger. And to do this, where we have the category image, I'm just gonna put category image dash dash and then large. So let's create this style. This is going to be category image. And I'm just going to put a here maybe dash dash large. And I just want to change the size of this into be to be height of three, three, zero pixels. Let's have a look. Okay, this works quite well. And let's copy now the card and paste a couple of times. I'm going to make a bit of space because this is a row and we just need more cards. One, two, three, four or five. I don't know how many I need actually. Can't remember. So let's check it out. Okay, one more. Let me put one more. This is obviously a demo. It's going to come from the database. Okay, that's looking good. Of course, we're gonna have a few more. We're gonna have like American food, Thai food, Indian Spanish, whatever we have on the list. And yeah, that's that's looking pretty good. The link is there. And the next section that we need to do, but I'm not going to copy the other sections just now because I'm going to do it from the database. And then we can just replicate them. But let's do the last section, which is to submit recipe. So let's go here at the bottom and maybe create another section. This, this is the latest here. I'm going to copy this and create another section. So this is going to be the submit section. I'm going to come at one time. And then inside here, let's do the let's do a section as we've started with sections. I wish I didn't the first one. I mean, we can change the first one is what it doesn't really matter. Let's do a section with the class name of PX for an MPY five and then my my five and then text center like so. And then inside this section, I'm gonna have an image. This image is going to have the class name of the block MX auto and be for image fluid. Then we need actually we need the image source. So this is going to be here. So the image source is going to be slash image and then publish dash recipe dot PNG. We do need an old text as well. So let's just add a here maybe. And this is going to be publish your or Ray today. We can definitely do with the width of saying five six six and the height to be 208 and then maybe 308 like so close this the next thing I want to do I want to have a title for this. So I'm going to put an h1 with actually this is going to be the title again. So let's do that and let's put a class name for the title of display five five FW both and then put the next section. Let's do a little paragraph. So let's do it with the class name of cold dash large six and then MX auto. I think that would do and inside here we're gonna have the paragraph. The paragraph is gonna have a class of late margin bottom four. And inside here we can do I'm gonna copy and paste some text publish your recipe in front of thousands of people for free. I'm just gonna do that publish your recipe in front of thousands of people for free. And I think that should do the job for now. And also let me tidy this up. So it's one one line. And then we can do another with the class name of the grid and then gap to the small flex justify content small center. And inside here we can do a link with href and then this is gonna go to a page called submit recipe that we're gonna create later the recipe and then this is gonna have the class name of btn btn primary btn dark btn large and btn large. And we're gonna say submit recipe. Okay, that's absolutely fine. We've closed the diff one diff to this okay, that's looking good. Let's test it out. Save it. Let's go back to the website refresh and the image seems to be broken. So let's have a look at least the old tag is showing. So this is gonna be didn't misspelling probably publish dash publish recipe that png I think I've called it. Let me have a look let me copy this name images and then okay, I misspelled the image is actually fine. I misspelled source. So this needs to be so src instead and save this and if we go back and refresh, you will see that the image is popping up. This is linked to submit page. This is linked to the submit page as well and yeah, that's not so bad. Okay, maybe the next thing that we could do is concentrate on creating a categories model and maybe we can just put some dummy data into the database so we can display and we'll work away from there. Okay, this is a great way to get into MongoDB and create some categories and then we'll do the more complicated stuff with the red recipes later on and let's go to MongoDB. So if you go to MongoDB.com register for a free account or paid whatever you wish and then just make sure that you sign in. I'm going to do that now and once you sign in, I'm going to zoom a little bit just so you can see a little bit better but once you sign in your dashboard will be probably empty. You won't have a cluster or anything like that but that's what you need to do. You will need to click on the create button here and create a free cluster. I think I believe that the first one is free. I've already created one as you can see says free shared and if I was to go and edit configuration just to show you super quickly, mine is based in Ireland. I think that was the closest free one that I can get and it says M zero sandbox shares from 512 megabyte storage and yeah, it says free forever. So create yourself a free cluster. I just don't think that I can create another one now. I might be wrong but but that's all you need to do is to create a cluster and once you then the next very important bit would be to allow yourself access network access. So if you click here network access, you will have to add your IP address. I've added my other computer as well. You will only be able to connect to your cluster from the following list of IP addresses and in order to add yours, all you need to do is click the plus sign here at IP address and you can even click on add current IP address and that would do it for you. Once you do that, this will add your IP address and you should be able to access your database but one more thing that you need to check out is the database access. You will need to create database access if there isn't one set up yet and in order to do that, you're going to have to just go here database access add new database user and just set up a password and make sure that you remember the password as well as we are going to need it. Okay, once you're done with this, let's go back to the database and the first thing that we need to do is click on connect. If you click on connect and click on connect your application, this will give you this code in here, which we're going to have to grab and put that into or into our environment variables. So this would be if we open the project, this will be into or dot EMV file that we haven't yet created. So let's create that dot EMV. This is going to hold all variables and maybe we can call this variable MongoDB underscore URI and that would be equals the line that we just copied. But the two things that we need to notice here that is your username, which I just showed you here. If you go back to database access, this is my username. And so I'm going to need my password as well. So I'm going to put that on right now. But we need to do is replace this with your password. And then the next important bit to notice is that this will be your database name. So you can change this now if you wish to or you can leave as the food and it will be just called my first database. I'm going to change mine to be called recipes like so. So this is going to be my database name and I'm going to save this. So let's exit this and let's set up or database connection. All right to do that. Let's open the Explorer quickly and let's navigate to the server and then models and inside here is where we're going to create or database connection. So to do this, let's create a new file and let's call a database dot JS. Inside here is where we're going to include well require MongoDB and connect to our database. So first of all, we need to include Mongoose. So we're going to do cons Mongoose and we're going to require Mongoose like so. Then the next thing that we need to do is connect. And to do that, we need to do Mongoose dot connect. And we need to pass the connection string that we put in our environment file here. So I can grab this from here and I can do process dot EMV to grab that variable and then the Mongo URI. So we're passing it here and inside here, we're going to pass a couple of options. And the first one is to use the new URL passer use new URL pass. And we need to send that to trip. And also we need to use unified topology and we need to set this to trees one like so. And then we need to we need to set the database connection cons DB equals Mongoose dot connection like so close this and then we can check whether we have connected successfully or we have an error. First of all, let's do an error DB dot on and then inside here, we put error and we want to maybe console logs something. I'm just going to use the example from the documentation. So console dot law sorry console dot error and then bind and then we put console and then with and then we can just put a message here connection error like so close this and then we can check whether the connection was successful when we can do this on DB ones DB ones open and then we can put a function here and then once it's open, maybe we can just console lock connected. Okay, that's it. And that would be it for database. And now all we need to do is create our first model. So I'm going to create a new file here and this is going to be called category model category dot JS and I'm going to put this with a capital letter like so. And the first thing that we need to do is include it in here. So require is sorry. So I'm going to put models and we need to require that model and it's going to be and dot and then category. Here it is. We don't need to specify dot JS or anything like that. And we're done. I think now might be a good time to create a very simple model. So what I'm going to do is close this close everything that we don't need and let's concentrate on the model. Now the model is basically a collection day of data and we can kind of like design the way or database is structured or collection is structured. Let me show you. I think this is a good starter because the category it's kind of like fairly simple. The first thing that we need to do here is require Mongoose const. Mongoose equals require and then we look at Goose like so and then we need to create a schema to create a new Mongoose schema we need to do is create a const. Let's call a category schema maybe and this will be equals to new Mongoose like so and then schema. Inside here is where we pass the options for the schema. I'm going to show you now. But before we do that, let's export this. So we're going to do module dot export. Export. Sorry. And this will be Mongoose dot model. And then we need to export this model as let's say category. And then we need to export this to we need to export this. So this will be your collection name, which I'll show you in a second. And that's it. So let's create a very simple Mongoose schema. So for this one, I'm just going to have name and an image. Let's put name. And inside here, we can just put a type and we can specify the type that we want for this. In this example, we're going to have string just because the name is going to be only text. And if you want, we can set it to be a required field. We're just going to insert some data. And that's it. We're not going to touch the categories too much, but the recipes, we will have to insert data from a form. So let's do required. And then this is required like so. And then to create another one, we need to do is put comma. And then we can even copy this. And the next one will be the image. And let's do type of string and this field is required. That's it. This is a very basic model, model story schema. And now let's have a look at how we can actually insert some data super quickly. And what more importantly, how we can display the data from the database. Alright, if I go back to the database and we click browse collection, you will see that currently there is no data in here. And let's have a look at how we can load some I mean, you can load some sample data, but I want to insert some categories with their with appropriate images and so on. So let me show you how we're going to do that. And then we're going to display them on the page replacing this row here. Let's go back close this. Let's go back to recipe controller. And first of all, I'm thinking, let's insert some dummy data. And I couldn't find an easier way to do that. We could do it through the command line. But I think this is going to be a little bit easier for everybody as well. So I'm going to do a very quick function and put some data in it. So this is actually going to show you a very simple way of inserting data as well. So okay, let's do an asynchronous function. First of all, I think this is going to be a function and I'm going to call it insert dummy category data. And then inside here, we're gonna have to wrap everything into a try catch. As this is a asynchronous function, we can wrap everything into a try catch. And what we have to do to insert data is literally a wait. And then we can grab the categories model, which we haven't yet put. So let's do that. So we're gonna have it in here. So const. So first of all, we need to require the database require. And then we require the database in here. So dot dot, thank you as models and then database like so. And then we need to require our first model. So const, this is going to be the categories category equals require. And then we require the dot dot slash models. And then category that's it. Now we can use this model to insert data. So inside here, await, we can put in here, await category, and then we can do and then we can use one of the inserts, one of the insert methods, which is called insert many. And inside here, we can put the data that we want to insert. And if for some reason this fails, we want to catch the error. And in this case, maybe we can just console locks and let's console lock. And we can just console lock the error. So maybe we can do it like error plus comma plus the error. And that's it. That's a very simple function that will insert some data. Obviously, we need to run that function maybe somewhere. I'm only going to run this once to insert some data quickly. And then I'm going to remove it. Maybe I can leave it for you if you want to reuse it. And I've already created some dummy data. So I'm going to copy that data if I can find it. And here it is. I want to show you the first is basically an array. It's basically the same as the model here. We have name and image and I've just put a few of them. So we have name, type, image, type food, name, American image, American food and so on. So I'm going to grab this. And what we need to do is insert it into here. I know it's a little bit of a cheat, but let's do it. So now if I was to refresh the application, that should run and hopefully we'll get some records inside. Okay, let's do it. Everything seems to be running. No errors, which is good. Hopefully if I go to MongoDB now and if I click on the refresh button, you will see that we have the database name created, which is called recipes. And we have the collection of categories inside here. One thing that you might want to look at is that all of the objects that we just inserted, MongoDB was clever enough to add a unique identifier for every single one, which can be useful in our application at some point. We probably won't use it today on this. We use on the recipes, but as you can see, it does add a unique identifier, which is pretty cool. And yeah, and that's it. So we have some data in here and now we can use this data to insert in here. Let's have a look at how we can do that. So I'm going to remove this obviously because we don't want to be inserting anymore stuff, but I'm going to leave it for you. When I upload the codes, I'm going to leave it for you to have. And now let me show you how we can do a query and how we can pass the object to the front page. All right. First of all, this is our home page controller. So everything is going to go in here. Again, we're going to have to wrap everything into a try catch. So let's do try. Sorry, let's do a try catch in here. Let me make some space. And if this succeeds, obviously we want to render the page. So nothing changes here. We are rendering the index page with the title cooking block home. If things go wrong, we could do, I mean, we could go to a narrow page. For now, I think it's just best to like maybe rest the status of 500. So let's do rest the status, something helpful for us. And then send message. E actually, that's be error. And then message. And then all error occurred. And that would be it. You can just console log if you wish. And now inside here is where we're going to create our first database query to grab the categories. What I'm going to do first of all is I only want a few categories. So one, two, three, four, five, five. So five categories is what I want. So I'm going to create kind of like a constant number for that limit number. And I'm going to equals this to five. And then what I'm going to do is create const category subject. And this is going to be equals a weight. And then we're going to grab the category model there and then do a weight category dot find. And we want to find everything. So we're not going to put anything in here, but I'll show you how to add filters later on. And I just want to limit this to the limit number that we just created, which is limit number five. And that's it. I mean, I could have put the five here, but I'm going to be doing a few more queries that are going to be using this number. So I think that will work well. And in order for us to display the categories, we need to pass this object that we're getting from the database. So what we're going to have to do is grab this. And just like we're passing the title here, I'm going to do a comma and just pass categories. So now if this succeeds, we should be able to use this and display the data. So let's head off to views and or front page. And let's find categories raising here. The categories, obviously, I'm going to remove all of them, except the top one, because we want to live free. And the last one was the view or button. So this is what we want to live free. Okay, so what we can do with EJS, let's start EJS. Let's end EJS here. And what we can do is let's check if the categories, sorry, if the category is not equals empty. And if it's not, we can do something. So let's put a curly bracket here and close it in here. Don't forget that. Okay. And now inside here is where we can do a loop. This is going to be a forage. So let's open EJS and let's do categories is a category or categories, categories, think categories dot for each for each, like so. And then we can do function. And then this is going to be maybe we'll put category and then the index. So now we open this with a curly bracket. Make sure that we close the EJS here as well. Don't forget that it's important. And we need to live through the whole bit here. So I'm going to close open EJS here, close the curly bracket and close the function, this one here. And actually, yeah, we don't need this one here. Sorry. So yeah, we close this bracket and we close this one here as well. And we end up, we finish the EJS. And now I can actually use this to display some data. So for example, we might want to display the image. So what I'm going to do is instead of image American food, I'm going to replace this with EJS. So this is going to be category dot image of life because we're going to the category and or database has the image here. So we want to grab that. Let me copy this again. And I'm going to replace this old text here with the category name. And I'm going to copy this again. And I'm going to put the category name here. Okay, if this works, I think everything, everything is looking good. Potentially we're gonna have to change the link is well in a second. But let's have a look whether this works. First of all, if I go back to the website and refresh, you will see that all of this is coming now from the database. And if I was to go to the database, I'm assuming and change tie, let's say tie 123 update this. So this is on the database. I just updated there. And if I was to refresh, you'll see that we're getting tie 123. And that's it. That's how simple it is to pull something from the database. And we'll be doing the same for the rest. Let me change this back. So it doesn't look ugly. Okay. And I was thinking since we have the view moment put two categories, maybe we can just change the link here to be categories and then the name of the category. So what's going to happen is let's have a look. So what's going to happen now this, what's going to happen is if however, you will see that this has the link of categories and then tie. So potentially we're going to be creating a categories page where we can list all of the categories by clicking on this button. And then if we want to click on a specific category, we should be able to do that as well and query all the Thai recipes or American and so on. Maybe we should do that now actually. All right, let's create or first other page rather than the home page and pull out all of the categories again. And then let's have a look at how we can get individual ones. So to do this, first of all, we're going to have to create a new page that we just listed here categories. EJS. So I'm going to put an H1 here. Categories and save it. We're going to have to go to the routes and create a new route. So this route is going to be get again, but we're going to get the categories categories and this one, maybe we can call explore categories, explore categories like so and save. So now we need to create this controller. I'm going to grab this close it, close the index and create a new controller just like this. So I'm going to face this for a second, copy all of this and let's just change get categories. So we know which one it is and this is going to be categories categories. Let's get this and change the export to home page to explore categories. And now we might just have to change this a little bit. I'm not going to do a pagination here, but what I'm going to do is just change the limit number to 20 or whatever. And then we want to render the categories page. So categories, the title will be, I don't know, cooking blog view or no, I don't know categories categories. We're passing the categories and we can do exactly the same thing as we were doing on the front page now to live through the categories. So what I'm going to do is go to the index dot EJS and I'm going to attempt to copy this first of all to see what I can make it work. And inside the categories, I'm going to face this first of all. So we're checking for categories. Yeah, I think that might work. Let me test the first and then we'll make it look better. Okay, so refresh. If I click on view all, it goes to categories. And as you can see, all the categories are listed. But for some reason, they're a little bit broken, which we're going to fix now. Okay, at least we're getting everything from the database, which is good. All right, let's fix this. So first of all, I'm going to create a class for the H1. Let me close this. Let me close this. So we're working on categories EJS. I'm going to put I'm going to put a class of padding bottom four, and I'm going to put explore categories like so. And then I'm going to put a breadcrumbs in here. So if you go to bootstrap quickly, get started breadcrumbs. And I think this one is good, maybe. Let's try this one. This is going to be the home link. And this is going to be the explore categories. So let's put that on. Yeah, that looks good to me. We'll see how it looks on the page. And then I'm going to create a row. So let's go with a class name of row, row calls to is it called to call call to I think it's called actually row calls large five g two g large three margin bottom for clothes. And I'm going to wrap everything inside this row here. Just push everything in. And now hopefully this will look a little bit better than before. Yeah, that looks a little bit better. We have the breadcrumbs here explore categories. We can go home if we click on this and we have a couple of categories. It doesn't look amazing. But obviously you can start this the way you want. And as I say, I'm not going to be doing pagination today. Otherwise, he's going to take far too long. And that's it. Now that we have the categories, what I want to do is actually when I click on a category, I want to pass the ID in here. So for example, tie and I want to display all the tie all tie recipes. But at the moment, we don't actually have any recipes. So we're gonna have to do that. We're gonna have to create a recipe model and insert some recipes in order for us to do that, which is a little bit annoying. So I think that we can do that now and maybe display some of the recipes in here as well. And we'll work away as we go along. Maybe we can do the detailed recipes when we click on them as well. And at the end, we're going to do the form. All right, let's do the recipe model now. So first of all, it's going to be exactly the same as the category one. So what we can do, let's go to category and copy this. Let's create a new file called recipe.js. And inside here, I'm going to paste everything and just change the naming. So instead of category, let's put recipe, copy this, change it here at the bottom. This needs to be recipe as well. And I think that's looking good. Of course, we're going to change the whole thing in here. So I'm going to remove all this and start from the top. But one more thing that we need to do is include it in the database.js file. So let's include recipe. And very important thing that we need to do is inside the controller, we need to include that at the top as well here. So this is going to be our const recipe. And it's going to be equals models slash recipe like so. And I think that's good. If we were to go back to a recipe model, we can start constructing this. So this is going to have a name comma, then we're going to have description. This is going to be a string as well. We can have an email. I'm only having a few, not too, not too many email can be a string as well. And as you can see here, we put in required on every single field. They don't have to be, but it's going to be helpful to have quick enough ingredients. This, this one is going to be a type of array this time, because we want to be able to add more ingredients like sugar, ice, water, whatever. This is going to be a game required, but yeah, that's fine. And then let's create another one. The other one is going to be Oh, make sure that we put commas everywhere ingredients. The next one is going to be category. Now I only want to have specific category. So I'm going to put in them, which basically only allows whatever we put inside here. And I'm going to have a few. So let's put tie American, Chinese, Mexican, and let's put Indian. Okay. We need to put a comment here as well. And what else do we have? And last we're going to have another one, which is going to be an image. This is going to be image. And this can be a string and it's required. Yeah, that's fine. Everything is looking good in here. Save this. And I'm going to insert some dummy data just like I've done it before. And I know it's a little bit of cheating here, but I'm going to copy this so I can leave it for you. So if you want to insert some dummy data as well, there's probably a better way of doing it. But let's do it. So insert dummy recipe data. I'm going to put this one on recipe data, put this in here to initialize the function. And of course, we're going to remove all this. And I'm going to paste some dummy data that I've copied from the Jamie Oliver website. I have put a the source link as well. And I've only put some of the information of each recipe. Obviously we need to give credit anyway. So I'm going to paste all the information here. As you can see, we have names to fry vegetables description source. That's part of the description. We have email different ingredients listed. We have category of Chinese image stuff, right? And so on. If I save this, make sure that we've saved everything, saved everything. And one last thing that I didn't do just now is at the top. I'm awaiting category insert many. So that needs to change to the one here to the recipe. We need to change the model. So we're inserting it into the correct one. Save this. Let's run the website and we're broken. Even can only be set an array of six string numbers, not mixed. Okay, let's have a look. Sorry, this is a string. That's my fault. So category needs to be a string. And hopefully now if we restart the server, that's so good. Let's restart. Okay, that that worked. But did I close MongoDB? I must have closed the page. So let's go back. And as you can see, we have the categories and we have another one now. Another collection here called recipes. Inside it, we have all the recipes that we just inserted. Don't worry, we will make the form so you can insert them with a form. But for now, I think it's just good to have some recipes. And the good thing about this is that each recipe has a unique ID created from MongoDB. We have the name, description, email, all of the ingredients here as an array so we can add as many as we want. We have categories so we can queries them by categories and we have the image. Let me show you how we can actually populate this with the database ones. I think that's gonna be fun. So what we're gonna do is let's go back to controllers. Obviously, this needs to be gone now. Otherwise, we're gonna keep inserting stuff. I'm gonna leave this for you. I don't know whether to leave it here to be honest, but I'll leave it for now and then decide later. All right, because because we're working on the homepage, we need to go back to the to the homepage controller. So inside here, the query is gonna be exactly the same as what we're doing here, but we need to query the recipes instead. And not only that, I want to only query the latest recipes to fill this one here. So in order to do that, let's do const latest and we're gonna do the same thing as above await. But then we're gonna grab the recipe model and put dot find. And this time we want what we want to do is if you want to grab we're not going to put any filters here. But if we just do this, it's gonna grab the first submitted the first submitted recipe, which we don't want with we want the latest ones. So to do that, we're gonna do dot sort. And then we're gonna do so with curly brackets in here, we're gonna do underscore so by ID minus one, just like so. And then we can limit this as well. So limit just like above I'm gonna limit it by five close just like so. That's it. We can technically pass this object into here now and display. But what I want to do because we're gonna be doing a few different queries, I'm gonna put everything into a food kind of object. So let's do const food. And then this is gonna be equals latest. And I'm gonna be adding a few more here in a minute. But it's gonna make sense when I do it. So I'm gonna pass this food object, which is gonna contain the latest one, the latest from the database. So let me show you what's gonna happen. I'm gonna copy this past this inside here. And we're gonna do the same thing that we've done with the categories. But we just need to go inside food and then latest. So if you go back to the homepage and find the latest here, so obviously I'm gonna have to remove all of these because we're gonna live through them with EJS. I'm gonna make some space so you can concentrate on this. So we could potentially do what we've done above. And we could do and if we could try if food is not if food is not equals empty, then we could do. Oops, so annoying. Okay. So close EJS here. Open EJS in here. Close the if statement. And now we can do a forage loop inside here. And I'm gonna show you something else as well. If we do now if we go into the food object and then we go latest, then we can do a forage and we can do a function. Then we can pass inside here recipe recipe and we can put index index open curly brackets, grab all this. Close EJS, wrap everything inside here like so. And let's have a look. And now I can use this recipe to populate the data. So for example, I want the link to be recipe and maybe we just put the recipe ID. So I'm gonna put EJS in here and I'm gonna put equals recipe. Let me grab this dot if you want to grab the ID, it's underscore ID. This is coming from the database here. This is the ID. So we're grabbing this number. And that's it. And now if we wanted to grab whatever we need, we have the image. So we might want to grab the image. So that would be recipe dot image. And we might as well grab the name for the old tag. I think we're gonna put it here and we'll put the name. I'm gonna copy this and just put it here for the name as well. And technically speaking, this should live through and display the latest products. Save this and hope for the best. As always, let's go back refresh. And as you can see, the images are broken. And this is because I actually want those images to be in a different folder. So this is going to be the upload. And when we add a recipe, all the recipe images are going to go into public uploads, but I don't have any of the sample images now. So I'm going to have to copy a few copy a few inside here just for the example and paste. So we have a couple of images now. We've changed the folder to be uploads where we can just do slash uploads maybe. And then if you go back, let's refresh. As you can see, these are coming from the database. And these are the latest recipes. I can if I was to remove the sort here, let's say we remove the sort, you will see that the result will change. There we go. The result is changing. And these I think these were the first ones added to the database. And that's why. So that's why we want the latest here. All right, we can do a couple of more here as well. So for example, we can do let's do the queries first, maybe, and then we can do them at once at the front. All right, so we've got the latest, maybe let's do Thai American and Chinese. So what I could do is do another query cons Thai and this is going to be slightly different. So we can do a wait recipe dot find and inside here, we can pass different filters. Now this is quite useful because for example, at this point, I only want to find the Thai recipes and display them on the front page. The way to do that is we can go into the categories. So each recipe has a category. This one has American. This one has Thai and so on. So we want to filter by category to do this, we can do find and we can put category like so in single quotes and then column and then we can put the category which in this case is Thai and we can also limit the results like so. And I'm going to put the limit number again and let's do exactly the same thing for the American and Chinese. So one, two, this is going to be American. This is going to be Chinese and if I copy this, I can change the category to American with capital A and I can change this to Chinese to Chinese with capital C. Now I can move those objects into one big field object. So we have latest. We have Thai. We have American. We have Chinese and we pass this as a whole into here and now and now I can reuse it. If you go back to let's close all of this. If you go back to the home page, we can now literally copy this section here and start changing it. So let's start with the Thai recipes. I'm going to make a lot of space so we can see and instead of doing latest recipes, let's do Thai Thai recipes. View more is fine. Maybe we can so this might need to be changed to categories and then we'll put Thai, but we'll we'll figure out this later on. Let's do it for now. Actually, just so that we don't forget. And then inside here, we check for food, food, latest, but we don't want latest. We want Thai and and everything else stays the same because we're using the recipe here to pull the data. So Thai food should be done. If we go back, refresh. We have the Thai recipes only, which is good. One thing that I wanted to show you is that sometimes if an object doesn't exist, you might get a problem and you could solve this instead of doing the if Thai food, you could do something else. You might have seen this before, but you could do type of food dot in this case, Thai. And then you can say if it's not equals equals undefined, obviously they are defined in the bone, you could do and percent and percent and then food dot Thai and then dot length bigger than zero. And then this should also work. So this could be a useful. Yeah, it's also working. This could be a useful trick if the object doesn't exist. That's another way of you checking whether this object is undefined. Let's have one more. So the next one is going to be the next one is going to be American so we can put American recipes. What else do we need American? Then that's absolutely fine. That needs to change to American American just so we don't get it. Let's just do with American not equals empty. A little bit easier. Okay, so that's fine. That's fine. And we should be able to get the American for that. So Thai American is all here. Lastly, let's just put one more just for this example. I'm going to get so this is going to be Thai. Let me tidy this up. Okay. This is going to be American. Thai. Okay, this is a little bit better. This is going to be what is a Chinese last one? Chinese recipes and one thing that I didn't do on every single recipe is to put an air statement. So if there is no recipes, we potentially want to say no items. So we could do this in here. Sorry about that. Else open. We need to close it. I can fix this quickly. Hopefully we'll be fine. And we can put a paragraph of saying no, no items found. That looks ugly. So let's put no items found like so. And I can possibly just replace this on every single one. Not a big deal. You don't have to have it. And place. And do we need the latest? Yeah. Okay. That's it. Hopefully this should all work. Okay. So we have we didn't change the last one, which is Chinese. I got caught up. Chinese for each Chinese. That's it. Now it is fine. Okay. Cool. So that needs to be changed to Chinese as well. Save. And let's have a look. Chinese recipes are working. American recipes are working. Thai recipes are working all good. If we click on view, these are working as well. Maybe we could have put this with the big image to the categories. But this matter for now. I'll say that we should do the detail view next. So when we click on a recipe, it displays a nice detailed view. So let's have a look at how we can do that. So first of all, let's go some of these. Let's go back. Let's go to let's start with the routes. So maybe we can put them on the recipe page. So let's do router. Dot get and this is going to be recipe. Then we need to pass the idea of the recipe that we want to display like so. I'm going to show you how this is going to work and we need to create a controller. So this is going to be the recipe controller. What are we going to say to this? I don't know what to call it. Maybe explore recipe. Explore recipe will do and close. All right. So now when we click on a product, we want to go to the recipe page with the product ID. And we want to query it and display the detail view. All right. Let's have a look at how we can do that. So we have the router here. We obviously going to need to create the recipe page, which is going to be here. So recipe dot the EJS. We're going to have to have. So let's say recipe for now. Let's close this. So the router is there. We're going to have to have the controller. All right. Let's copy the categories one and we will change it. So let's this is going to be a get recipe with the ID slash dot ID. And let's say recipe page. And this needs to be changed to the one that I just created. So explore recipe like that. We're not going to need the limit here because we are only grabbing one. Obviously we're going to use the recipe model and we need to change the queries as well. So let's change all this. You know what? Let's let's delete all of this and start from beginning. So this first of all explore recipe we've changed. That's fine. So we have rest or render and we want to render the recipe page. So let's do that. Recipe the title can be whatever you like. But for now let's remove this as well. And now let's build it from scratch. So first of all we need to grab the ID of each recipe. So if you remember on a homepage every single page every single recipe has an ID if you see at the bottom left corner. So we want to grab that ID in order to get the recipe. So to do this we can use the rec.param. So let's do rec.params. So let's do let recipe ID ID equals rec.params and dot ID is to get the ID. This is the ID from here. You can call it whatever you like. That's what we do. And now we just need to do a query on the database. So we're going to do const recipe equals await and then recipe dot find by ID this time and then we're going to pass the ID. So we're creating the ID and we should get one object only and then we just need to pass the recipe in here us like that. And now we can render it. So if everything has gone well we should be able to go to first of all we can even probably click on let's select let's refresh click on item and it goes to recipe. That's that's good. And as you can see we have recipe and we have the recipe ID which we're grabbing. Now we can display all of this data with EJS. So if we go to the recipe dot EJS we might as well build the whole page and what we can do is let's start with EJS. So if recipe is not equals no maybe then we can close or if it's not equals empty we have to try this and then close. Okay. This is all if statement and we're closing everything everything else is going to be inside here. So if this works we're going to say H1 works. Let's test it and we're getting the narrow and this is because okay this is because I didn't open curly bracket here and let's close it. All right works. That's good. And now let's build our page. I'm going to grab some breadcrumbs from what's the categories. I'm going to grab this paste them in here. So we have home and maybe we can have the active one to be the recipe ID. No sorry that's not even linked. So that's fine. That's fine. So what I'm going to do is just put the recipe name in here. I think so I'm going to start EJS put dash and then close EJS like so and I'm going to put recipe dot name like so if we save this refresh as you can see the recipe name is coming up and we can now continue. Let's create a row for this one deep class of row like so and inside here we're going to create a couple of columns. So we're going to have a first column for the product image of this with a class of cold 12 one will mobile we want it to be forward and then we want cold middle to be for inside here. Let's add our image. So this is going to be image source and this is going to be equals uploads. Slash and then we can grab this actually and just hopefully just change this to image and then let's put a couple of classes to make it look nice. So we can do image dash fluid sticky dash top sticky top is just nice to have it look cool. I think and maybe I'm going to put style and the style I'm going to put top of 20 which you'll see what's going to happen. Probably do need a note. So let's put an old tag and just put recipe dot name for the old tag and do it and let's put load in lazy lazy like so. And that's it for the image. All right. For the next bit we're going to have kind of like the information of the recipe. So let's do another column with the class name of cold dash 12 cold dash medium 8 and this is going to have a row class row and this is going to have a class sorry another dip with the class of cold dash 12. So we're creating another column and inside this column and create an H1 with the recipe name. So it's nicely displayed. Then I'm going to create another column here dip class of cold 12 medium. Don't really know and if you remember only in this tutorial we added bootstrap icons. So I'm going to use one in here. So I so I'm going to add an icon here. So this is going to be I with a class of bootstrap icon bootstrap icons tag may just to make it look nice and I'm going to put show put I'm going to put the recipe recipe category here. I think that's going to look nice. And then we can have the instructions or descriptions. So in this case we're going to have this with the class name of cold dash 12 style. I'm going to put white space and I'm going to tell you why for this pre dash line. And this is basically if we don't have white space between the lines when we set into the database all of the takes might be cramped and my I'll show you in a second if I can find an example. And I think that's going to solve the problem. And then here let's put like H4 something and let's do cooking instructions instructions. Then let's put the recipe description. What else do we need? We need the ingredients but for the ingredients I'm thinking of creating another row where is this row? Okay. I'm going to create another row inside here. So this is going to be with the class name of row but in top form and we're going to do another difference inside here with the class name of cold 12 inside here. We're going to put a story H4 ingredients and for the ingredients we're going to have to put an order list. Now let me show you what I'm going to do here because the ingredients themselves are actual array actually want to display them one by one in the list and in order to do that I'm going to have to do a for reaching here. So a little bit of work but it's going to be nice. So this URL is going to have a class of list group list group flush and inside here we're going to have a list and each list is going to actually we're going to loop for each list. So let's do the for the for loop. So what I'm going to do start the JS come on study JS and then recipe dot ingredients and then we're going to do for each and then function and then we put the ingredients it doesn't have to be that long you can make that a little bit smaller if you wish and then index and then we put open curly brackets close curly bracket but we need to we need to grab those two close easiest here. Because we're looping we need to open a JS here closer with the two brackets. So curly bracket and normal bracket close the JS like so and inside the list we can then put class name of list group dash item and inside here is where we can add the ingredients so we can do some like ingredients and hopefully this would let me just tidy this up a little bit. So it's on one line. Hopefully we should be able to look through this list and display all the ingredients for each product and I can put that inside like so and one last thing if something didn't work maybe we can put an else here open it and close the I key for getting this else do we need? Yeah, we need a curly bracket and we need to put a message for my job. So no item Okay. Hopefully if I've done this correctly we should go back refresh and as you can see we have the image here we have the title we have the category maybe we need some space between a cooking instructions ingredients and they're all nicely listed and as I said I've taken this from the Jamie Oliver website it's only for learning purposes if I'll show you if I go down actually if I put the browser to be a bit smaller this is one of them with the sticky I think it's just nice effect nice to have definitely just playing around let me just put space in here save let's okay a little bit of space and if you go back we can see that we have I don't know if we click on any of them like let's say this one we get the recipe everything is working and yeah that's that's pretty cool so the next thing that we can do is potentially do the category so if I go here and if I click on a specific category I want to only display American food or Chinese food or Mexican food so this is going to be very similar to what we've just done first of all let's find the category page and change this a little bit so let me open a category category, category, here we go so categories I want this image can I do the category image large maybe at least it's going to look a little bit better it's going to make me feel better those images are too small okay ignore this, ignore this nobody saw this I think the images of half are too small for this so I didn't choose the right images anyways we want to link this as you can see all of them are linked categories American, Chinese, Mexican Indian so on so when I click on this I want to only query the one that I've clicked on okay let's have a look at how we can do that so we're going to still use the same page and let's go to the routes and let's create another category route shall we move it here so you can see let's move it right category we're going to create another category route this time this is going to have an ID as well we're going to pass an ID just like we did with the recipes this route is going to be still get and let's say explore category by ID maybe by ID I think that would work save this and now let's go into controllers and create it so I'm going to copy all of this or shall we copy the the category one let's copy the category one and maybe we can have them sitting together as well like so so ignore the recipe for now maybe okay we concentrated on this one here sorry about that categories and then we put slash an ID just so we know category ID something like this first of all we need to change this so it's explore categories by ID then we need to grab the ID from the page so to do this let's say that we do let category ID be equals rec.params.id so this is how we're getting the ID of the category and now we can let's leave the limit I don't mind and then let's say let's say that we have category by ID and this is going to be equals await category find and we need to put another filter so we're going to look for category and then category ID is where we get this from the parameter I'm losing and okay we need to pass this instead now and let's have a look at how this is going to work because this page already has all this so let's have a look okay so if I was to click on this we're having category is not equals empty interesting we might have to do the trick with the type of here because yeah we might have to do the trick with the type of because this does not exist anymore let me try that first of all so we're going to do type of categories not equals equals undefined categories dot length bigger than zero then we do this okay let's have a look whether this breaks again okay this doesn't break so that fixed it and now I can do can I do the same from the front page I want to grab kind of like this gonna grab this and see whether we can modify so I want to display this so what I'm going to do is do exactly the same thing here but we're going to say where is it we're going to say category by this what we're passing so we're going to say if type of category by the is undefined category by the length is equals is bigger than zero then we want to do for each and then we want to put the recipe ID image name name that's fine or not found maybe we need to remove this but that's we'll do that second okay that's all working the only thing that is not working now is the okay we're looking for the categories again okay we need to look for recipes now so that's why recipe find category category ID so yeah I needed to change the query and now if you go back and we do that as you can see we're getting the type recipes I should have put have you put a link back to make it a little bit more intuitive let's say let's do categories okay so now if I click on categories we get the categories here put Chinese we get in a few if I put American we're getting the American ones and they're all linked to the recipe with the ID so if I click on one we're getting that and then if we click on that we're getting that and so on so yeah pretty cool I think I'm going to consider this is done now potentially you could put the category name here instead but that's pretty easy to do with TGS as you already know how to do that I'm going to leave it and what else do we have everything is working here we need to create the search I think this is a good one actually so let's create the search page now okay and this one is going to be different to the other ones this one is going to be post so let's copy this but just change the post we want to post to the search page so search like so and we have can do for the search should we just do search recipe search recipe like so and that's it I think post okay so we need to go to recipe controller and make one let's title this up beautiful we need it around here so I'm going to copy this paste that this is going to be post and this is going to be search and this is going to be search and we need to create the search page as well but before that I'm going to grab this just render it so I'm going to do rest or render in here and I'm going to render what do we do what do we do let's remove this and let's just do search and let's do search is the page that we want to render and this is the controller okay that's it so now if we create a search page let's do that each one search let's see if this works first of all but post on this we're going to search and the reason this is working is because if we go to the main layout in the header if you remember we had the phone here the phone has the method of post at the action of search a very important thing in here is that the search to grab the search term I've put the name to be called search I think that looked like it's misplaced but yeah search them is what we need to grab in order to do the query so let me make a note of this and we can do the query now actually and then build the page let's start by doing the same as always try catch for the catch I'm just going to copy this bit here and now let's do first of all let's get the phrase so this is what we need to get so this time might be a little bit different so let search term be equals rec dot body we're going to use this time because it's coming from a form and then we're going to put search term that's how we get the search term now if you wanted to do the query it's actually fairly simple we're going to do let recipe equals await and then we're going to do recipe the recipe object then find and then we want to find now this is a little bit tricky here we can't just search in MongoDB that easily we're going to have to do some magic here so bury me I'm going to do some crazy stuff in here let's do text and then we're going to have another filter in here which is going to be search and then search term and then we're going to put the die cryptic sensitivity to true so die cryptic sensitivity true okay bury me here otherwise we can't just do a normal query like this we need to do it this way and also we need to go back to the models recipe model in particular and we need to say in which fields do we want to search from so if you go back to MongoDB as you can see there is a lot of fields in here so we can just well we could just put a wildcat and search in all of them but in this example I want to show you how we can search maybe keywords from the name and let's say the description maybe so let's do that in order to do that we need to index them so we're gonna have to go back to the recipe model and inside here we're gonna have to use the schema that we created recipe schema and do a little index so the index and then inside here we can pass the fields that we want to index which and name and we need to just put this as sorry text like so and we need to pass the description in this case description and then we put this as text okey dokey that's it hopefully that should work and one one more thing if you want to do the wildcat I haven't tested it yet but you could do potentially wildcat index in you could potentially do the same thing recipe dot index but instead you could do I think it's going to be a dollar sign sorry in double quotes dollar sign ashris ashrics and then it's going to be text I haven't tried this yet but I think this is how it's going to work I'm going to leave it here for you to try if you wish and that's it so let's have a look whether this is going to work what we can do just for a quick example instead of rendering things let's just do res dot jason we're going to render the recipe just to see what we get okay so if I okay sorry if I refresh maybe want to get salad let's put salad and if I search you will see that we're getting only one result and is the tie chicken inspired pinch salad okay this seems to be working so we can definitely render that now to do this let's do what we always do do I not have restaurant Oh here it is okay we need to move this inside here so rest or in the search title do whatever you like and we just pass the recipe in here with the dot recipe all right I'm going to render this all right we can render this we can go to the search page and build one super quickly now so I'm going to go here and let's start with an h1 you know what I think we can copy most of it from the home page let's have a look so maybe we can copy this I think that we can do yeah let's copy this from the home page and let's just do it in here so we'll change everything so this needs to have a class name of padding bottom to be for search results and then inside here that's absolutely fine we just need to change this to recipe and obviously we need to change the for each leave which is fine that's fine now I think that should be okay okay if we refresh you see that we're getting the recipes nicely displayed and if I was to click on one we get in the recipes which is good let me search for one more what else do we have carry a search for carry we're getting only two carries here tie red chicken soup and tie green carry have a click on one we're getting everything working and now I think we're almost getting there some recipe and I think now we're almost getting there I think I can show you how to I've already kind of showed you how to do the latest query for this but if you wish we can do it all right let's do the explore latest show random and then we can do the form at the end so to do the explore latest then this link as explore dash latest so we're going to have to do this what is it called route there we go so this is going to be a get route I'm going to copy one of them and I'm going to put it here so this is going to be explore latest and maybe we can just do explore latest like so and put them all together obviously we need the page as well so let's do we could duplicate the search maybe let's do explore latest.ejs explore latest or we've got so many open now okay sorry about that let's close everything we're going to need this anyway so explore latest is get we're going to need to let's grab this one so we're going to do explore latest this is going to be get explore latest for latest and for the query I'm going to do this from scratch so maybe we do the same as the other ones we just do comes our limit number and we put that limit number to be 20 or whatever and then we can do comes recipe equals weight and then we get the recipe dot find inside here we don't put anything as we just want the latest and I've done that earlier actually we're going to do just sort and if you wanted to sort out by latest inside here we just put underscore ID and then minus one that should do the job then we can put the limit if you wish limit not sorry limit and then inside here we put the limit number like so we already passing this object so I could potentially just go to was it the search that we just done and grab this I think actually I'm going to grab everything just pasting here change that now and hopefully that should be it so if I was to refresh explore latest and we're getting recipe ingredients for each Oh, we changed the controller but we didn't change the rendering page we need to change this to explore latest and that's it I think that would be it cool let's have a look fresh and if we click on explore latest we're getting the latest products in here and that's it I'm going to leave this one as done so I'm going to click on this and it's working or let's now do the show random and I'm actually just going to show you how to do it but you can figure out how to how you want to display I'm just going to show you the query and maybe we can just display the data so just to speed up the process and so the button was called so random dash recipe okay so we need to create that if you go to the route then inside here we can do random recipe I mean ideally I wanted to be the same explore random so I'm going to go back to is it the homepage I think it is and just change it to explore random just so it's the same and when we hit that URL we want to explore random recipe okay, let's do the controller and I'm not going to do the page as you've already know how to display that or let's do it in here so I'm going to grab all this and I'm going to put that in here explore explore random as Jason so I'm going to remove this I'm going to remove this as well okay, let's start from beginning so if we hit that URL I just want to show a random recipe to do this we are first going to need to count the actual document how many documents do we have so to do this let's do let dot count sorry, let's count equals await recipe dot find and then we need to find the count of the document and now we can use this to make a random number out of it so let random equals math dot floor and then inside here we can do math dot random and then we can do times the count that we're getting from here and we close and the last thing that we need to do is query so let recipe I'm going to use the same name object here actually doesn't really matter that much recipe as I'm going to dispatch Jason and then await and then we can do recipe dot find one this time just one we need to find and then we can skip to the random number that we just generated and execute this like so and I'm going to display this as Jason to speed up the process as you already know how to render stuff Jason and we put the recipe I mean I could do a different page for it I could do let's do that let's see if it works first of all okay refreshed if I push show random as you can see we have crab cakes if I refresh we have another product another product so it's all random if you want to display this to be completely honest we're gonna have to create a new page to that and I'm just thinking can we just use the explore latest I'm just going to do it like that I mean you can display it however you want but let's do I'm going to copy all of this gonna create another page and I'm going to call it explore explore and don't mean yes that's fine explore random now we just need to render this page so we're going to go back to the controller and instead of rest or Jason we just need to rest or render and then random hopefully this should display a random recipe and no it's not recipe for each recipe yeah we can't use for reaching this situation because we only have one result I don't think that we can use for reaching here so that's a maybe that was a good exercise so let's have a look if I refresh here it is and I probably wouldn't display like this I'll probably display the whole information somehow but here it is it's a random one and if I refresh another random one appears I don't want to waste too much time on this because you can start it the way like and that's it so this is the random one and now finally we can maybe concentrate on doing the actual submit form for the recipes all right this is going to be a big one doing the form so let's get going so where is the phone so maybe so we have some me recipe and we have some me recipe links so we need to create this page first of all so let's go ahead and do that so I'm going to do another router here it's going to be submit recipe and the controller for this one is going to be submit submit recipe and that's going to be submit recipe so now we need to create this submit recipe page and let's do it in here Regis and then each one submit okay we'll come back to this so now that we have the route here that's cool let's create the actual and by the way this is going to be get just to say this is going to be okay let's go to the controller so let's do in here let's just make sure that we just render the page for now so what I'm going to do is grab this now I'm going to grab all this just to like a simple render so let's copy this render here and we're going to render submit recipe submit recipe the only thing that I'm going to do is remove this and maybe do submit recipe like so that's it and I need to change the controller this cool all right hopefully the page should be working now so if I go back refresh submit recipe we have the submit page and now we can start building our form this is going to be a big one so okay hopefully it won't take too long let's go into it let's close everything else that we don't need and let's just concentrate on this first of all let's do a little bit of a title for this one so let's do a diff of class of px for py five my five text center so many classes h1 class display dash five and then both and this is going to be submit your recipe inside here we're going to have another diff with the class of co large six mx also and inside here we're going to have a text so this is going to be with the class name of lead and I'm going to copy some text copy paste and that's it so this is all nice now it's the form okay for the form let's create a diff with the class name of row and justify content center inside here I'm going to have a column of eight and then inside here we're going to have the form so basically I've made the form slightly smaller than 12 columns and I want it to be in the middle and then we can start creating the form in here so there are a couple of important things to know about so first of all form action this is going to be submitting on the same page so submit submit recipe one important thing that we need to make sure that we put these the n c e n c type to be equals multi part from data and this is because we're going to be submitting an image as well and very important the method needs to be set to post okay now that we have the form we can start adding some fields hopefully once we do one we're going to be able to duplicate them and speed up the process so let's create a row first of all so diff with the class name of row and gap three if that works and then inside here I'm going to create a diff class of call 12 and inside here I'm going to start adding the first input so the label for this one is going to be for email the class is going to be form label and this is going to be email let's create an input the input will be the type of email the name will be email the ID doesn't email cool so what's important here is the name we're going to be grabbing the input information using this name here so you can name whatever you like but you need to remember that and then we can do the same for the rest so I'm going to do a name and then recipe name then I'm just going to put name everywhere except this type needs to be text and we're done the next one would be the description let's add that description type of text absolutely fine actually the description needs to be text area okay text area name description ID description calls 30 rows let's go for and remove this because we're going to be adding a bit more for the description that's why now let's copy this for the next one which is the ingredients and then for this maybe we can do a little example be our and we can do small example I don't know ice to I don't know let's just put ice ice then we're going to have the input which will be called ingredients with small I it's going to have the ID of ingredients actually we're going to remove this because I'm going to show you something a second what we want to do for the ingredients we actually want to be able to duplicate this input so we can add more ingredients such as sugar water eggs whatever you know so we want to be able to duplicate this we might have to do some a little bit more work on this but let me add a button it's going to be a ugly one but who cares for now this class of cold 12 for the button and then let's do a bootstrap button so button we're going to do type of button then we can do class name of btn btn outline and then primary and then we might have to add an ID for this just so when we press it we can duplicate this year and we're going to have to do this on the front end with JavaScript so let's call this one at ingredients btn and I'm going to put plus ingredients ingredient one okay alright we might have to wrap this in a diff so we can easily grab it and duplicate it so what I'm going to do is let's put a diff here with the class name of ingredient list okay let's wrap everything in here and I'm going to put one more diff with the class name of ingredient diff and maybe when we add ingredients we might want to have what we duplicate this sorry we want we want want to have margin button a little bit so I'll put one the next bit that we're going to do is the categories so let's create another column here so diff with the class name of cold dash 12 this one is going to be different this one is going to be a select menu so let's do a label for category category and then we can do a select and then we can do a class form select form control the name is going to be category a label is going to be category like so then inside the select obviously we're going to have to put some options this one is going to be the selected one and I'm just going to put select category and then let's put some options so this one is going to be with the value of tie if you remember when we did or recipe here we put this as enum which means that we can only have those categories here if you try to insert anything else rather than them it's not going to work is going to say an error is going to give you an error so just have that in mind and that's why we've put it in here otherwise this could be hacked I can always change this with HTML but we have the enum set in here so technically we can hack it so even if you change the HTML you won't be able to submit this what I'm saying and then we're going to have tie and then we're going to have how many more one, two, one, two, three, four, I think so this one is going to be American this one is going to be Chinese this one is going to be Mexican and this one is going to be Indian cool that's done for the options what else do we have? we have select image this is going to be slightly different as well so let's create another diff with a class of coal dash 12 and this is going to be a label or image product image and then this is going to be an input but slightly different input this is going to be type of file and this one is going to have the class of form control and it's going to have the name of image and we're going to have accept and here we can put what we want to accept I'm going to say I want to accept all images but you can specify whether you want to accept on the JPEGs or PNGs or whatever so I'm going to accept all and last we're going to create a button so diff with a class of coal 12 and I'm going to do a button with type of submit and then this is going to have the class of btn btn primary and I'm going to say submit recipe like so let me just double check something text area I didn't add the class to text area this one wanted to check so class it's going to be form control I think cool that's it so we have pretty much everything that we need here let me have a look all right so if I refresh we have some things are not working I think I've missed the class made on them so let me have a look super quickly so about that is probably the form control class so if I go to the top input yeah okay class form control class form control and then the rest should be okay yeah everything is looking good the form is looking good so if we go to submit we have submit your recipe and we have all of these things the ingredients doesn't seem to be working so ingredients, ingredients, ingredients it's going to be this one here form control and that's it before we do anything we might have to wire this up we're going to have to do some JavaScript in order to be able to copy this so we can add more like sugar ice whatever and yeah let's do that so first of all we're going to have to go to our main layout and have a look at whether we have a custom JS file which we don't so but do a view wrap I'm going to put a custom JavaScript in here so I'm going to do script with the source and the source will be slash JS which is going to be a public folder and inside here I'm going to put a script so this is going to be script dot dot JS and I'm going to try this straight away so I'm going to create a script JS and let's save this and one thing I can do whoops one thing I can do is just do an alert now this is a front-end JavaScript by the way hello world let's save this if I refresh we're getting a lot of so the JavaScript works which is great I can remove this and now I want to be able to copy this input using the class of this and this and I want to copy it on the press of this button here with the idea of add ingredient button so this is going to be an interesting one I'm pretty sure that it's so easy to do with the frameworks but with pure JavaScript is a little bit of a hell to do so let's do it so first of all we need to select the button the button was called add ingredient btn it's here add ingredients btn I can even copy if you wish don't need that so add ingredients btn is equals document dot get element by ID and the ID is add ingredient button and now I need to grab the ingredient list so this is going to be add ingredient this one here sorry ingredient list so let's do let ingredient list is equals document dot query selector because this is a what is a class name I'm gonna have to do with a query selector now I'm gonna have to grab the diff is one here so let's do let ingredient diff equals document I wish bush shop had this option but probably this I just don't know about it so document query selector all and I'm gonna grab the first ingredient diff object by doing this it's gonna make sense in a second so what I have to do now is do the on click and then listener and I can do it on this button so if we do add ingredient btn and then add event listener this is gonna be a click and this is gonna function and then inside here we're gonna do some magic first of all we need to clone this ingredient so to do this let's do let new ingredients equals ingredient diff dot clone clone node is the one I need and then that should be set to true and then we need to grab the input and the reason I'm grabbing the input is just just in case if there was a value in the input and you decided to add more values you don't want to copy what's inside the input so I'm gonna do let input equals new ingredients dot get element by sorry this one is gonna be get element by tag name and I want to get the input and I want to get the first one right now I want to reset this value so input dot value is equals nothing and then lastly I want to append these to the ingredients so I can do ingredient list dot append child and I want to append the new ingredient it's a little bit confusing this one is but hopefully it will work so if I was to go to the form refresh and if I click add we are adding more ingredients which is what we want I'm not gonna do the reverse now I'm taking far too long and now let's have a look at how we can actually submit the information and upload an image and get some flash messages actually that might be the next thing to do let's set up the flash messages just because it's it would be easier to set them first and then work with them later all right for the flash messages we're gonna have to go back to app.js and we're gonna have to insert the rest of the dependencies that we installed early in this tutorial if you haven't yet installed them don't worry you can just install them now it's not a problem but I'm gonna require them here and then we're gonna make it work so it's gonna be quite a few of them let's might as well put the file uploader so let's do const file upload and this will be equals require and we're gonna require the express file upload like so and then we're gonna need the session so const equals require and we are requiring the express sessions express session sorry and then we need the cookie passer so const cookie passer equals require and then we have the cookie passer like so and we also want the flash messages so const flash equals require and then connect flash I can't believe how much how many dependencies we need to add to make the connect flash work I'm not sure whether there is a easier way for this but I've already made a specific tutorial on this as well if you want to check it out but I'll explain as much as I can in here and now we need to set a few things up under here I'm gonna put some more middleware of course so we're gonna do app.use and we're gonna do cookie passer and this is gonna accept first of all we need to put something secure here so cooking box secure very secure close this and then we need to do app.use and then we need to put session and inside here we can pass a three options actually the first one is secret and we just need to put some secrets so let's put secret session and save initialize we need to put as true and the last thing that we need to put is resave we need to put as true as well and we also need to do app.use flash like so and file uploader app.use file uploader file upload okay that's it I think that's it that's all we need let me close this save and now we should be able to use the flash messages and the file uploader first of all let me create the submit page so the submit route sorry so if we go I'm gonna remove this now remove this now and if we go to the let me see server route route okay we need another route for posting the data so this is get but we need one more to post so I'm gonna do router post we're posting on the same page submit recipe but we do need to change the controller so submit recipe I don't like how both okay maybe we can do on on post I think that's descriptive enough and now we need to create this so we're gonna go to controllers and just underneath here is where I'm gonna create it so I'm gonna copy this and I'm gonna start with post submit recipe submit recipe yeah that's correct I'm gonna change the export here to submit recipe on post we do not want to render here because this is on post we probably want to redirect instead redirect and we can't pass anything else in here now that's why we're gonna use the flash messages and that's it I think they should do the job save everything we can remove this remove this and let me try to post something okay so I'm refreshing it too good I click post and we're getting submit recipe cannot post okay redirect actually I need to put the page I need to put slash here so that's probably the reason I hope so if I refresh and for some reason this doesn't seem to be working now which is very strange and I believe that I've made a little mistake here and is this power upload needs to be like that hopefully this will fix it I hope so yeah okay a tiny little mistake but it breaks the whole application so if I was to go back to submit recipe and we submit as you can see if refreshed and nothing happened so the submit is now working that's all we need we just need to press redirect and now we can actually start looking into the flash messages which I think is probably best to set up now so let me show you how they work for example we usually pass objects in here and if they are not undefined bad things happen we need to check you know that but okay so let me show you how we can do the flash messages so I'm going to try to explain as much as I can here I have made videos on this before but let me show you so first of all I'm going to set an object so maybe we can call it info errors object info info errors object like so and this is going to hold all the errors that we want to display to the user so when we can do and to use flash messages we can do rec.flash and then we can give it a name so info errors is what I want so this is going to be for the errors but I want one more for the success messages and this could be info submit submit object and this could be rec.flash and then info maybe submit and and in order to be able to pass this to the actual page we're going to have to just pass them one by one here so we can do info errors object and info submit object just like so now obviously they are empty at the moment but what we can do now is if we submit something maybe we can try the info submit the successful message and to do this to be to be able to use the flash message what we have to do is inside here on post so we're going to go here and we're going to do rec.flash message like this like rec.flash and then we're going to put the message that we want to flash so this is going to be the info submit message and then in here we can pass whatever we like an object or even a string so I'm going to write something quickly recipe has been added like so and I'm going to leave it obviously we're going to use the other one as well when we have an error so let me show you how we can do this first of all if we go to bootstrap and if we go to messages maybe alert I want one of them basically so I want this one and this one here so this is the success I want gonna grab that I'm going to pull that on the page here at the top maybe maybe around oops maybe around here in the middle so this is going to be the success message and what we can do is check for that so as we are passing this info submit object I can grab it and I can do with EJS I can do if info submit object is not equals empty then we need to open like so and close EJS in here so if this is empty we're not going to display anything and to prove that this is working hopefully we can go back refresh and nothing is happening we don't have anything but if I was to submit something and actually I want to get the object name so might as well do that now so I'm going to do dash info submit object and I think that's it so we hopefully we should be able to get recipe has been added let's have a look I'm going to go back refresh and then submit as you can see recipe has been added I definitely want it inside here so let's fix that maybe maybe I can just do it inside here and I can do as a call eight so let's do alerts actually let's just do call eight I think that would fix it make it nice okay and now if we go back refresh it's gone if I submit its recipe has been added and now let's have a look at how we can wire the form and how we can display some errors and that will be the last bit of the tutorial so first of all let's do it with dummy data I always try to do it dummy data first of all and on submit so this is on submit so this is where we're going to be doing the submission and let's do the usual so we're going to do try catch try catch and if we are successful we want to say yes we've added something with the flash message but if it's not then we can we can flash the error so what I'm going to do so I'm going to grab this I'm going to do recto flash grab the error one and we can pass the error object in here like so and that's it we can also redirect as well to the same page and that should work and now let's try to submit some data to the database finally and to do this too add a new document we can do const maybe we can do new recipe and this will be equals new recipe which is our model here at the top so I'm going to grab that I don't need to do that but I just wanted to show you so I'm going to grab that new recipe and then inside here is where we add the data so what I'm going to do now let me close this what I'm going to do now is add a bunch of data so if you remember our model we have a name description email ingredients category image all of them are required and let's do that so first of all let's start with name and I'm going to add some dummy stuff new chocolate cake then let's do description and then we're going to do then we can do email for the email we're going to do a lot of ready.co.uk for the ingredients we're going to do water and for the image not for the category if you remember the only category is that we can use from the enum here at Thai American Chinese Mexican and Indian so I'm going to do Mexican and then let's do image and image I'm just going to pass an image that is already in the uploads folder and let's have a look if we have any I have any okay I'm going to grab this one here so let's grab the name so it's not empty really that's all and that's it now that we have created this if we wanted to save it we can do await await new recipe that we just created above and then we can just do dot save like so and that should save to the database obviously this is dummy data so on submit is going to save if it fails it's going to go here and it's going to display an error we have to do the same thing for the error here so we're going to have to do the same thing but it's going to be info what is a sorry info error object so info error object info error object and this is going to be a danger thing and that would be a and I think we might have to go inside the this object but I'll show you why in a second so hopefully if we go to the main page of the website this is the latest product here so if we submit a new one let's have a look obviously let me let me submit a new one so obviously this is not working just yet we're submitting the data that we just hard coded so submit a recipe has been submitted if I was to refresh we have the new chocolate cake here I click on it and it's all good basically all the information that we just added so that's working it's also if we refresh the database we'll see somewhere at the bottom I believe here it is new chocolate cake cool now if we did have an error let's say we didn't fill all of the all of them are required by the way so if we didn't fill one of them it should technically error so I'm going to remove the name and if we refresh now and submit you'll see object object and the reason for this is is because this is giving us like an error object which we can play with here so what I'm going to do just to show you rec.json I'm going to display as json and I'm going to put this inside the json here and display so this is going to make a lot of sense in a second so I'm going to submit oh it's not res it's rare sorry it's not rec it's res json I thought straight away okay here it is so I submit errors name name and message this field is required so it's realized that this name this field is required and now potentially we could use this to display it obviously it's so zoomed in to display in our form here but the laziest way and probably not the so good way the laziest way is to literally just grab this message for now but you can play around by grabbing each individual error if you wish I mean I can try but let me show you with the message so if I was to obviously we need to remove this and if I was to go back and inside here put message hopefully it should display the message did I remove the res json I think I did okay refresh did I not save it save okay I didn't save it probably save this refresh and it's not working I think I think it's because we need to go inside the object my fault so we need to go to the first one so okay recipe validation field name this field is required so this is the laziest way and if we haven't submitted the rest obviously it's gonna display the rest and basically that's how we can play with the validation obviously this is coming from the back end which is good it can't be disabled wow if we do it with JavaScript on the front end it's nice with the user experience but it can be disabled and I just wanted to show you in forms you can get somewhere in forms validation if you wanted to do that I think it would be nice to do that but it's just gonna take too much time now you need to basically follow this form you can maybe copy it I think on the form you need to include needs validation what else do you need? obviously you need the valid feedback stuff I'm probably gonna miss something I definitely need the JavaScript and you're gonna probably input this JavaScript on the front end JavaScript in public if you remember public JS this is where you would include it and yeah just mess around the other way you can do it for example maybe we can do for the name I can just put required and the browser will handle this so if I go back and if I submit look at this this field this field is required and you wanna be submit which is really good I can do the same for the rest now one last thing that we need to do is submit the data from the form which you probably already know how to do that but this point we can just replace all this so name okay so let's replace all of this with real data I'm gonna leave the image for last because we need to do something with that as well totally forgot okay so this basically to get the data from the form we're just gonna do rec.body and then name name is the name of the actual field so if you go back and have a look at this this is what it is this is the name from the field then we have description here we have ingredients and so on so that's why we're doing that make sure you put comma and I'm just gonna copy this now and just you know what I'm gonna paste it everywhere and hopefully change it okay we don't want the name everywhere so I'm gonna put description here email here ingredients here category here and for the image let's leave it for last everything else is looking cool so hopefully if we refresh this and input something so I'm already new recipe from form then we can just do description we need some ice we need some water and we need some sugar okay category let's put a style image we're not gonna do now submit recipe has been added if we go back to the front page you will see new recipe from form that we just added obviously is using the same image I added ice water and sugar all looking good and now let's quickly build a form because it's quickly build the form now sorry the upload the upload image I'm gonna quickly build that now is well I do have a detailed video on this but let's just build it inside here super quickly it's not gonna be reusable or anything like that let image upload file and this is actually from the official documentation on the express file uploader and let me close all this close all this okay so let the image upload file let upload path we're gonna put the path as well let new image name and now we're gonna check so if rec.files or object.case rec.files it'll make sense in a second and then we need to check for the length six equals zero then this is gonna fail is gonna say that no files were uploaded so we can maybe console lock something lock and we can just say no no files were uploaded else oops let's close this and else we can do we need to get the name of the input so image upload file is gonna be equals rec.files and then this is gonna be equals image I think come remember what is image now excuse me submit it's image yeah okay so image close this and then we're gonna do new image name is equals we're gonna get the date now because I want to have a unique name for every every single image that we upload and then we're gonna do plus image upload file dot name and then we just need to set the directory upload path is equals require and then we require the path and to resolve to the main directory and go into the public upload we're gonna have to do dot resolve and then we're gonna do plus slash public and then slash uploads and then slash plus the new image name that we just created and the last thing that we need to do is write the file so image upload file dot and be upload to the upload path that we just put and this is gonna be a function and this is gonna have an error and if we do have an error we can just check if error and then return actually return rest dot status and then 500 dot send error okay so what we have to do now is replace this with the new image name so yeah we need to replace this with the image name which comes from above and I think hopefully if we are lucky we should be able to upload an image and the recipe at the same time all right so let's start hello new recipe with image sugar we can add more sugar sugar then Chinese then we upload an image I'm gonna upload my logo here submit recipe has been submitted if we go back you will see that my logo is in here and if I click on it it's displayed and it's all looking nice and that's pretty much it from this tutorial I know that there is a lot more to do but I think this is pretty cool so far all right and the last thing that I wanted to show you just as an add-on to this tutorial is how to actually update the record and how to delete one we're not gonna do any forms or anything like that I'm just gonna show you the query by now you should be able to pass data create forms read data yeah and push data to the database so let's have a look at a very simple query of updating a specific recipe for example let's grab this one here so what I'm gonna do is let's go back and let's open the server controllers and recipe controller and anywhere really I'm not as I said I'm not gonna do anything special I'm just gonna do the query and when we refresh the website I just wanted to run that's all and so you can have it here and then I'll come at it out so to update a specific recipe should be fairly easy to do first of all I'm gonna wrap everything into an asynchronous function so let's start by tapping that here async and this is gonna be a function and let's call this function update recipe like so and inside here we're gonna wrap everything to a try catch just like we've done everywhere pretty much and for the try we're gonna say const response equals await and this is what we do our query and the query will be recipe recipe because we want to update the recipe and we can just do the update one there is as you can see there is update many as well but we're just gonna do one in this case and let's say that we wanted to update this recipe here with the name of new recipe so I'm gonna grab the name so let's put name put the name inside here so we can update it and then if you wanted to update this to something else we can do comma and inside here we can pass the new value some name and then maybe we can put a new recipe updated like so let's close this close this as well we can display the number of documents match so we could do the response and then end and that is from the official documentation this says this will be number of documents matched and then we can do res.n modified and this will display the number of documents modified okay I'm not gonna do anything else here for the error we could just console log something let's just console log the error and that's it so to run this function let's just put it inside here and run it obviously we don't we're gonna comment this in a second so it doesn't run all the time otherwise it's gonna keep updating the recipe right technically speaking if I was to refresh now you will see that we get a new recipe updated and this is how easy it is to update a record and the last thing that I want to show you let me I'm gonna leave this for you just so you have the query here but obviously this needs to be commented out and the last one that I want to do delete recipe and this is gonna be exactly the same I'm just gonna remove all this so we're gonna do constress and in fact we don't even need this so let's remove this so I'm gonna do a white recipe and instead of update one we're gonna do delete one as you saw you can delete many as well and the one that we want to delete is the new recipe updated so I'm gonna remove all this remove all this and so here it is so wait recipe delete one with the name of new recipe updated delete recipe we need to run this function this time and that should delete the recipe so if I go to the front page you will see that the recipe is now gone and maybe we can delete this one as well so let me see new recipe from form let's delete this one as well save refresh and it's gone so that's how you delete recipes update recipes add recipes and that's pretty much it I'm gonna comment this out as well so delete recipe and I'm gonna put a come for this one which is update recipe all right I'm gonna leave these here just so you can have the queries and I'm gonna tidy up the data here I'm gonna leave this but for this one I'll probably won't leave all the data I'll probably just leave one with some dummy data and that's everything from this tutorial I hope that you found it useful please consider subscribing to my channel it would help me a lot and thank you very much for watching as always my name is ready and you're watching my channel ready to brand and I will see you in the next tutorial