Build a Recipe Blog using Node.js and MongoDB (Express, EJS, Mongoose & more...) CRUD

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what is going on everybody my name is ready and you're watching my channel ready the brand 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 going to show you how to run the 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 going to 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 they search for something that would also work and so on and the last thing that i'm going to show you is the publisher 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 am using windows so i can do left shift right click open powershare window here and this is basically going to cd to my project folder but if your 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 c dot and so on anyways to initialize a new project we need to do npm init and i'm to put the dash wi-fi 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 npm i is short for install and then we can list all the dependencies that we need so we're gonna start with connect flash then we're gonna have the cookie parser we're gonna add we're gonna have dot env we're gonna have ejs we're gonna have express uh express ejs layout express file upload [Music] express sessions and mongodb and the last one is mongoose so 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 i'm now we're done we can open or 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.json you will see everything that we just created the dependencies here and we also want to add node one so every time we 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 and let's do npm install nodemon and then save as this is a development dependency this should take a second and if we go back to package.json 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 gonna have to google the errors that you're getting and so on anyways if you want our project to run with nodemon we need to go under scripts here and add a new line so i'm gonna do comma and the line will be start column and then inside here we want to start our application with normal and then application file will be called app.js which we are 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 our 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 gonna 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 when 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 gonna do const express equals require and then we require express like so then we need the express layout const express layouts require and then we require express ejs layout like so and the layout will be basically very helpful when we create or template for our website we will 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 env and then port number but because we are working on log host i'm just gonna say one manually so we're gonna do all port 3000 like so we need to also require dot emv this is going to be for storing or database details so we might as well do that now uh to require.tmv it's 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 so remember to add it and let's put dot emv it's 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 middlewares here and the first one is the express url coded and this will basically allow us to pass euro encoded bodies so let's do that super quickly we can do app.use and then express dot url encoded and inside here we just need to pass one option and that option is called extended and then through like this and close then we need to set up a static folder and i will and i will explain so app.use express dot static and or static folder i'm just gonna call public now what this is going to do is every time we require something to our html such as images scripts stylesheet 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.jpg that would be a lot better than listing the whole folder and that's why we're creating this public folder which we'll create in a second as well as soon as we finish this we also need another middleware which is for the express layout so let's do use express layout and for the layouts we need to set a main folder so we're gonna do app dot set and this will be layout it's gonna make a lot of sense in a second so the layout folder that i'm gonna use is gonna be called dot layout and then main all right this is where we're gonna store our layouts and our main layout is gonna be just called main then we're gonna have to create some route and we might as well start building our folders and everything so let's do const route and equals require and we need to require our route which we haven't yet created so this will be server slash slash routes and then uh let's call a recipe recipe rouse.js and we want all apps to use those right so we're gonna do update use and then slash and then route like so that's all good and the last thing that we need to do is to make sure that our app is listening on this port number so let's do app.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 another function inside here and just console.log something and i'm gonna cause the luck with the backticks single back ticks i'm gonna cause a look listening to two ports 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 are setting it here and all public folder is gonna have a couple of things it's gonna hold all styles so css it's going to hold or images i'm gonna shorten this to img and it's gonna hold all front-end javascript and potentially will probably hold the uploads as well uploads here and that's it we'll create the files in a second the next thing that we probably want to do is our server folder which will have let's have a look this will have a 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 our database 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 all 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're using 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 route let's create our first route which is recipe route so reciperoutes.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 [Music] express like so and then we do const 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 gonna create now uh in fact let's create it 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 that file const recipe controller equals require and then we require the recipe controller which will be backwards ones 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 gonna actually have to export this so we're gonna have to do module dot export 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 to asterix and inside here i'm going to say app route 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 uh create one just to test the application i'm gonna use router and then the first one is gonna 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 just so the description is makes sense so let's do home page homepage 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 controllers recipe controller and we can create our first route and test the page now to do this let's make a little comment here so slash and just so we start 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 our 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 on page like so and that's it so in order to use this we're gonna have to do export [Music] 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 a narrow function like so and inside here is where our logic is gonna go for every single page obviously we're gonna have different uh 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 res dot 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.js is actually called main.ejs because we're using ejs my fault and let's put this into layouts this is going to be all mail art actually it is already there and inside views i'm going to create or first page which is for index page or home page you can call it whatever you like i'm going to keep as index dot ejs and this is going to be your home page and this is going to be our main layout now let me show you how this works so 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 layout 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 start djs 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 uh h1 of hello [Music] world and save all 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 npm start and press enter if you see nodemon's starting nodemon uh 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 node 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 dot set and then view engine like so and the view engine that we're using is ejs and we're done alright 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 world now the interesting bit is that if i was to inspect the code i'm going to do control and new 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 home page 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 it will be very easy to maintain all right let's close this and let's go back so that's all good let's close this let's start building our main template all right so we're going to be using a lot of bootstrap in 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 and that needs to be equal by the way and inside here we can do type of title tattoo 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 blog dash made wait 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 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 all objects so i could do something like title and then just provide a title from here let's just say home page for now so let's have a look so it's not going to use the default now anymore if i refresh it's going to say home page and this is how we pass the title and then if i refresh this you will see that it says home page so let me change this to something like uh um okay uh it doesn't really matter too much obviously make sure that yours is a little bit more seo friendly i guess but that's just an example i'll 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 uh setting up bluestrap 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 uh 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 uh 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 gonna do the bundle one so this needs to be put at the bottom so let's copy this and let's work it here at the bottom and that would do and then i want the icons so for the icons let's have a look [Music] 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 uh you can npm install it but i'm just gonna use it from a cdn so let's have a look install here we go here we go this is what i want so the two ways of doing it we can either use the link or we can import it into a stylesheet 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 [Music] 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 uh with a link or you can import it into straight into your stylesheet i'm gonna do the link for now so let's copy this and paste it inside here and the last thing that i'm gonna do here in the head is include my own style 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 stylesheet so link rail stylesheet 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 thinking talking about earlier with the public if you do app.js this is where we set our 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 gonna 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 i don't know 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 it's coming from bootstrap and that's why it's slightly different okay this is pretty good so far we can now start working on our layout 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.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 center line 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 gonna have padding on the x-axis middle and then five background i'm gonna set to white and i'm gonna put shadow [Music] 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 html5 tag and i'm gonna wrap it like so i think this is gonna be good and also i'm gonna need some sort of a header and a footer so what i actually originally what i've done is actually search for boost wrap five templates and if you click on this link here which is getbootstrap.com docs 5.0 examples uh 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 um but yeah if you wanted to do that to save a little bit of time i mean to be 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 it's probably just the right click edit html and just ctrl a to grab everything copy here 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 oh or homepage just says hello world but as you can see this is working i'm going to build my own one just because uh i want it slightly different but i should it shouldn't take too long so first of all i'm gonna need to include my images by the way so let's go to the images folder and reveal in file explorer at the moment it's 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 the 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 let me close this close close and let's build the header 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 for not explaining any everything else because i don't want this to turn into a bootstrap tutorial so this is gonna be a header and that's gonna have a lot of class names we're gonna 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 three margin bottom of four border bottom we want and then inside here i'm gonna add the first one which is gonna be a link and that's gonna be my logo so i'm gonna do a href then i'm gonna put slash because i want my logo when we click on the logo i want it to go to the home page and then i'm gonna put a class name oops class name is equals and then this is gonna be d flex and then align item center that's correct and then call md free margin button to margin bottom middle screen of zero text dark and text decoration [Music] none because i don't want the the link to be underlined and inside here i'm gonna use my image so i'm gonna 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 229 which i 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 alt i'm gonna put something like cooking blog made with node.js and close this okay 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 unordered list is going to have a lot of classes there's going to be a nav with a call of 12 co middle auto uh margin bottom two justify content center and then margin bottom margin sorry middle of zero and then inside here obviously we're gonna have all links they're gonna 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 uh but this one is gonna be let's say the home one and i'm gonna have a class name of nav link padding to the x y x axis of two and then link secondary like so secondary color and then this is gonna 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 and i probably won't even end up making all those pages there 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 a 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 but you can add a button if you wish to it's totally up to you so we're going to do a div with the class name of co middle dash pre and then text end and inside here we're going to create our form so this form is gonna be it's gonna have an action of search so we want when we submit this point to go to search but don't worry i'll come back to this one and 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 gonna have a name and the name is quite important this is how we're gonna pass the data so i'm gonna just make it very kind of like obvious search thumb and then let's put a class name of form control and then placeholder is going to be equals search dot dot and then area area label [Music] level is going to be equals search for accessibility and that's it okay i think this is good here we have the header we'll test it in a second i'm gonna do a very basic footage as well so inside here let's do a footer 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 y the the y of five so this is up and down and i think i'm pretty happy with this as long as it works of course uh 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.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 uh yeah here it is rubrik 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 root 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 this is going to be sans serif like so hopefully this should reset the font now if i refresh this should change here we go the fonts have changed the typography 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 gonna do container dash xxl and i'm just gonna reset the max width to this so i'm gonna do 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 our 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 gonna change i'm gonna change to something like rgb oops i definitely don't want this no i don't know this hey the rgb the rgb is gonna 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 you we won't be able to see them now but the bootstrap links are usually blue so i'm just gonna 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 var 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 all good if i do okay that's pretty good for our main layout and now we can actually start building our home page where it says hello world okay let's start building the homepage 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 stylesheet.css open just because we'll probably end up writing a few styles but uh we are now pretty much done with the main layout so let's close that as well and let's jump into our homepage which is in views index.ejs so inside here we're gonna have to build a few things let's make it pretty first of all and then we can populate it 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 for this and i'm going to show you how i've done it as well okay so i'm going to do a div with the class name of row so on your row on inside here i'm going to do flex large row reverse align items center gap 5 padding y 4 n margin bottom or four inside here we're gonna have another column so this is gonna be a div with the class name of co 12 and co dash large six so on mobile we want the column to be full width while 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're gonna add or hero image so let's do an image with the source and the source will be image and then hero image image.png and then this is gonna have a width let me close this so okay this is gonna have a width of six zero seven a height of five ten what else do we need a class name of the block mx la uh lg auto image fluid to make it responsive uh maybe we can put loading lazy as well on it of course we'll probably need an old text as well so cooking with node.js will do for now and then we need another column so let's do another div with the class name of code-12 and this is gonna be the same as above large six six excuse me and inside here is where we're gonna have all hero text so i'm gonna do an h1 here and i'm gonna say let's say class name display [Music] dash five uh font weight volt and then imagine bottom three and for this i'm gonna put huge selection of delicious recipe ideas in this like so and then i'm gonna add a little bit of text as well so 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 lead and you can pause the video if you wish to copy it but of course you'll probably have your own one i assume but this is going to be explore or huge selection of delicious recipe ideas including easy desserts delicious vegan and vegetarian dinner ideas gorgeous pasta recipes quick bakes family friendly meals and gluten free recipes that's pretty cool we also want two buttons underneath this so i'm gonna create another div inside here so div with the class name of uh now d grid display grid gap 2 d md flex and then justify md start like so uh this is gonna hold all two buttons so a href they're gonna be links so href this one is gonna be maybe like explore latest recipes explore latest and this is gonna have a class name of ptm vtn primary [Music] vtn dark vtn large and then um fighting on the x uh 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 it this one is gonna be maybe we can do a random recipe from the database [Music] and the recipe btn btm outline instead i think and then this is gonna 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 mashed it with an image from unsplash.com that will be linked will be credited 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 uh here is the image it's masked as you can see so and we have two more blobs on the outside and i'm not too sure whether i'm gonna 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 other image exactly the same here i've put three blobs and just matched a few images from unsplash.com and i think that it turned out all right 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 layout is working nicely and then we're gonna obviously populate it with real data from a database so let's do that next and 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 starts let's create another one categories end okay inside here we're gonna create a div with the class name of row row cause two row cos dash large six and then g two g large three and p y four i'm not gonna be over explaining the class names anymore as i've already probably explained most of them and then inside here is where we're gonna have the categories as links so inside here we're just gonna create a couple of links so let's start with a href and this potentially 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 a link is going to be a custom class that we're going to create uh usually you could have a category as your main class in here but i'll probably want to 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 uh mask it kind of like have it as object fit so he always fits the card i'm gonna do a div with the class name of category underscore underscore image oops underscore let's go underscore image and then shadow [Music] like so and 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 this 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 attack of food let's do that let's have a lazy loaded [Music] lazy potentially i'm not going to put width and height on this one but because we're gonna have it as object fit uh 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 gonna do a div with the class of pt dash one now i'm actually wondering whether this and i'm just gonna put american food and now i'm wondering whether this needs to be kind of like h3 something but it's inside the link so let's leave as it is okay though so this is gonna be our card and we're gonna have i think five of them maybe so maybe we can just uh duplicate this five times for 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 start this now all right 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 a category link so category this is a class name of category link and i can do text align center i probably already didn't actually with bootstrap i want to display as block i want the text decoration to be none if we have any links and let's do let's do a hover over effect a simple one transition let's do our 5 250 milliseconds oh and let's do a little hover effect here so category link and then hover and i'm just going to scale it so i trans that is transform isn't it transform scale of 1.1 close this for the next bit let's do the image now so the image would be category under [Music] underscore underscore image and then what i'm gonna do is display this as flex i'm gonna justify the content to be center [Music] align items center height let's put is 100 pixels margin bottom is going to be 10 pixels and let's put a little bit of a box shadow around so this is going to be 0 pixels 3 pixels 6 pixels and i'm going to put rg rgba of 0.0.0 and then point sorry 0.16 i think that should work and then overflow needs to be set to none we don't want the uh sorry too hidden we don't want the cut the images to overflow and then i'm gonna put a border radius of eight pixels for the corners lastly we want to make sure that our image insight 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 width 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.djs so this one i'm gonna change let's say so the image is going to be called view or dot jpeg i think i'm going to change the alt tag to be view or view categories loading lazy that's fine and then this is going to be saying view oh and the link the link could be potentially categories i haven't yet decided on this categories i think that would make sense so if we save this refresh uh we have kind of like a view all button i've kind of cheated and photoshopped three dots in here uh 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 sections 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 with 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 gonna copy this and i'm gonna say latest i just put latest start and then latest and like so um inside here is where we're gonna put the latest recipes now for this i'm gonna create a section here so let's do did they 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 gonna have a class or paren bottom four padding top four and i could have used the padding i could have used the other one and then we can do a div with the class name of d display flex margin bottom of two align items center and then inside here we're gonna have a title so with h2 i'm gonna put latest recipes [Music] latest uh recipes like so um we're gonna have a link on the other side so this is gonna be href with the link of probably explore latest let's leave it like this class name will be ms auto to push it on the other side so this is gonna be or view more button like so and then underneath here is where we're gonna have every single recipe like the cards so let's do a div with the class name of row and then row cause two row cos large five and then g2 g large three okay not too bad now inside here we're gonna have very similar to the top we're gonna have a link for the card so href and this is going to go to recipe and then we'll probably have an id in here which we'll add later on 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 gonna reuse the category link class [Music] like so close this and inside here again to be fair we could just copy this i think let's have a look uh yeah we could just copy this thing 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 gonna put the image of this one here and let's put the name of anna [Music] chocolate banana fee i'm gonna copy this put it as an altex 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 gonna 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 modifier for this to make the image a lot bigger and to do this where we have the category image i'm just going to put category image dash dash and then large so let's create this style this is gonna be category image and i'm just gonna put it here maybe dash dash large and i just want to change the size of this into the to be height of 330 pixels let's have a look okay this works quite well and let's copy now the card and paste it a couple of times i'm gonna 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 gonna come from the database okay that's looking good um of course we're gonna have a few more we're gonna have like american food thai food uh indian spanish whatever we have on the list and yeah that's that's looking pretty good the link is there um and the next section that we need to do uh but i'm not gonna 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 okay this this is the latest here and i'm going to copy this and create another section so this is going to be the submit section i'm gonna comment one more time and and then inside here let's do the um let's do a section as we've started with sections i wish i'd done the first one i mean we can change the first one but it doesn't really matter let's do a section with the class name of px 4 and then py5 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 gonna have the class name of the block mx auto mb for image fluid then we need actually we need the image source so this is gonna be here so the image source is going to be slash image and then publish recipe dot png we do need an old text as well so let's just add it here maybe and this is going to be publish your for ray today we can definitely do with the width of saying 566 and the height to be two or eight and then maybe loading lazy 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 file by fw vote and then for the next section let's do a little paragraph so let's do a div with the class name of co 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 lead 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 actually 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 [Music] and then we can do another div 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 h ref and then this is going to 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 btm dark btn large and vtn large and we're gonna say submit recipe okay that's absolutely fine we've closed the div 1d 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 spell it probably publish dash publish recipe.png i think i've called it [Music] let me have a look let me copy this name images and then [Music] uh okay i've misspelled the image is actually fine i've missed the source so this needs to be sir 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 uh 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 uh put some dummy data into the database so we can display and we'll work our way 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 right 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 gonna do that now and once you sign in i'm gonna zoom a little bit just so you can see a little bit better but once you sign in your dashboard will be probably empty uh 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 it 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 m0 sandbox shares ram 512 megabytes 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 about 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 will 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 setup yet and in order to do that you're gonna have to just go here database access at new database user uh 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 gonna have to grab and put that into or into our environment uh 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 env this is going to hold all variables and maybe we can call this variable db 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 gonna need my password as well so i'm gonna put that on right now but all you 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 good my first database i'm gonna change mine to be called recipes like so so this is gonna be my database name and i'm gonna 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 gonna create our database connection so to do this let's create a new file and let's call it database dot js inside here is where we're gonna include well require mongodb add connector or database so first of all we need to include more goose so we're gonna do cons mongoose and we're gonna 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 uri so we're passing it here and inside here we're gonna pass a couple of options and the first one is to use the new europasser use new url pass and we need to send that to true and also we need use unified topology and we need to set this to true as well 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 log something i'm just gonna use the example from the documentation so console.lo sorry console.error and then bind and then we put console [Music] 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 once db once open and then we can put a function in here [Music] and then once it's open maybe we can just cause a lot connect it 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 uh category model category.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 under dot and then category here it is we don't need to specify.js anything like that and we are done i think now might be a good time to create a very simple model so what i'm gonna 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 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 mangoes cons mongoose equals require and then we require goose like so and then we need to create a schema to create a new mongoose schema we need to do is create a cons let's call it category schema lady [Music] 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 sorry and this will be mongoose.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 gonna 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 gonna have string just because the name is going to be only text and if we want we can set it to be a required field and 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 all 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 mode sorry schema and now let's have a look at how we can actually insert some data super quickly and well more importantly how we can display the data from the database all right if i go back to the database and we click browse collection you will see that currently there is no date 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 um so let me show you how we're gonna do that and then we're gonna display them on the page replacing this row here all right 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 excel uh this is actually going to show you a very simple way of inserting uh data as well so okay let's do an asynchronous function first of all async and this is gonna be a function and i'm going to call it [Music] insert dummy category data and then inside here we're going to 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 weight 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 uh thinkus models and then database like so and then we need to require our first model so const this is gonna be the categories category equals require and then we require the dot slash models and then category that's it now we can use this model to insert data so inside here a weight we can put in here a weight 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.log something let's count the log and we can just console log the error like so uh 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 it see 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 thai image thai food name american image american food and so on so i'm going to grab this and what i 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 unique identifiers 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 any more stuff but i'm going to leave it for you when i upload the code 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 homepage 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 catching here let me make some space and if this succeeds obviously we want to render the page uh so nothing changes here we are rendering the index page with the title cooking block home if thing goes wrong we could do i mean we could go to a narrow page for now i think it's just best to like maybe raise the status of 500 so let's do rest.status something helpful for us and then send message e uh actually that's the error and then message and then all error occurred and that would be it you can just cancel log if you wish and now inside here [Music] this is here is where we're gonna create our first database query to grab the categories what i'm gonna 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 gonna create kind of like a constant number for that limit number and i'm going to equals this to 5 and then what i'm going to do is create const categories object and this is going to be equals a weight and then we're going to grab the category model there and then the weight category dot find and we want to find everything so we're not going to put anything 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 would 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 gonna have to do is grab this and just like we're passing the title here i'm gonna 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 uh let's find categories crazy here the categories obviously i'm going to remove all of them except the top one because we want to live for it and the last one was the view all button so this is what we want to loot through okay so what we can do with djs let's start djs 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 [Music] okay and now inside here is where we can do a loop this is going to be a for reach so let's open ejs and let's do categories is a category or categories categories i think categories dot for each for reach like so and then we can do function and then this is gonna be maybe we'll put category and then the index so now we open this with a curly bracket make sure that we close djs here as well don't forget that it's important and we need to look through the whole bit here so i'm going to close open egs 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 like so and this is going to be category dot image i believe because we're going to the category and our database has the uh 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 uh i think everything everything is looking good potentially we're gonna have to change the link as well in a second but let's have a look whether this works first of all so 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 let me zoom in and change tie let's say tie what to free update this so this is on the database i just updated the uniforms to refresh you'll see that we're getting tai 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 [Music] okay and i was thinking since we have the view more button put to categories maybe we can just change the link here to be categories [Music] then the name of the uh category so what's gonna happen is let's have a look so what's gonna happen now this what's gonna happen is if i hover over you see that this has the link of categories and then tie so potentially we're going to be creating a categories page where we're going to list all of the categories by clicking on this button and then if you 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 our 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 gonna have to create a new page that we just listed here categories dot ejs so i'm gonna put an h1 here categories and save it we're gonna have to go to the route and create a new route so this route is gonna be get again but we're gonna get the categories categories and this one maybe we can call explore categories explore categories like so unsafe so now we need to create this controller so i'm going to grab this close it uh close the index and create a new controller just like this so i'm going to face this reset 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 [Music] 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.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 paste this first of all so we're checking for categories uh 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 gonna 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 gonna create a class for the h1 let me close this let me close this so we're working on category cjs i'm gonna put i'm gonna put a class of padding bottom four and i'm gonna put explore categories like so and then i'm gonna put a breadcrumb in here so if you go to bootstrap quickly get started breadcrumb and and i think this one is good maybe let's try this one uh this is gonna be the home link and this is gonna be the explore categories so let's put that on uh yeah that looks good to me we'll see how it looks on the page and then i'm gonna create a row so let's go ahead with the class name of row row cause two is it called call call 2 i think it scopes actually row cause large 5 g2 g large 3 margin bottom 4 close and i'm gonna wrap everything inside this row here uh 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 breadcrumb here explore categories uh 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 it'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 thai and i want to display all the thai all thai 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 our way 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 alright let's do the recipe model now so first of all it's gonna 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 dot js and inside here i'm gonna paste everything and just change the naming so instead of category let's put recipe [Music] copy this change here at the bottom this needs to be recipe as well [Music] and i think that's looking good of course we're gonna change the whole uh thing in here so i'm gonna 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 cost recipe and it's going to be quiz models slash recipe like so and i think that's good if we were to go back to 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 uh we can have an email i'm only having a few not two 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 gonna be helpful to have we're gonna have ingredients this this one is gonna 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 again 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 commerce everywhere ingredients the next one is going to be category now i only want to have specific categories so i'm going to put enum which basically only allows whatever we put inside here and i'm gonna have a few so let's put thai american chinese mexican and let's put indian okay uh we need to put a comma in here as well and what else do we have and last we're gonna have another one which is gonna be an image but this is going to be image uh 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 honest 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 the me recipe data i'm going to put this one on recipe data put this in here to initialize the function and of course we can 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 name stuff right vegetables description source well 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 are inserting it into the correct one save this let's run the website [Music] and we broke it in them can only be set an array of six string or numbers not mixed okay ah 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 they 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 uh inside there 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 uh we have the name description email all of the ingredients uh here as an array so we can add as many as we want we have categories so we can increase them by categories and we have the image right let me show you how we can actually populate this with the database ones right 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 but 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 going to 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 uh const latest and we're gonna do the same thing as a buff await and 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 going to grab the first submitted the first submitted recipes which we don't want we we want the latest ones so to do that we're going to do dot sort and then we're going to do so with curly brackets in here we're going to do underscore sort by id minus 1 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 going to be doing a few different queries i'm going to put everything into a food kind of object so let's do const food and then this this is going to be equals latest and i'm going to be adding a few more here in a minute but it's going to make sense what i do so i'm going to pass this food object which is going to contain the latest one the latest from the database so let me show you what's going to happen i'm going to copy this pass this inside here and we're going to do the same thing that we've done with the categories but we just need to go inside period and then latest so if you go back to the home page 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 we can do and if we could try if food is not if it is not equals uh empty then we could do oops so annoying okay so close ejs here opening js in here close the if statement and now we can do a for each loop inside here and i'm going to 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 [Music] then we can pass inside here recipe [Music] recipe and we can put index index open curly brackets grab all this close djs wrap everything inside here [Music] 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 going to put ejs in here and i'm going to 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 going to put it here and we'll put name i'm going to 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 and 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 sword you will see that the result will change there we go the result is changing and these are i think these were the 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 uh at once at the front end alright so we've got the latest maybe let's do thai american and chinese so what i could do is do another query const thai and this is going to be slightly different so we can do a weight 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 tie 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 tie 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 i want to this is going to be american this is going to be chinese [Music] 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 we 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 uh maybe we can so this might need to be changed to categories [Music] 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 [Music] and everything now stays the same because we're using the recipe here to put 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 type period uh you could do something else you you might have seen this before but you could do type of food dot uh in this case thai and then you can say if it's not ecosequence undefined obviously they are defined at the bottom uh you could do an percent ampersand and then food dot uh die and then dot lymph [Music] bigger than zero and then this should also work so this could be a useful uh yeah it's also working this could be a useful trick uh if the object doesn't exist that's another way of you checking whether this object is undefined and let's have one more so the next one is gonna be the next one is gonna be american so we can put american recipes whatever 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 uh empty a little bit easier okay uh so that's fine that's fine and we should be able to get the american through that so thai american is all here lastly let's just put one more just for this example i'm gonna get so this is gonna be thai [Music] let me tidy this up okay ah this is gonna be american thai okay this is a little bit better uh this is gonna be what did it say chinese last one uh chinese recipes [Music] 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 and we need to close it i can fix this quickly uh hopefully it'll be fine um we can put a paragraph of saying no [Music] 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 uh you don't have to have it and there's space and do we need the latest yeah okay that's it hopefully this should all work okay so we have oh we didn't change the last one which is chinese i got caught up chinese uh forage 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 uh chinese recipes are working american recipes are working entire 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 for the categories but doesn't matter for now i'll say that we should do the detail view next so when we click on a recipe it displays it in 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 route so maybe we can put them under a recipe page so let's do router dot get and this is going to be recipe then we need to pass the id 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 uh what are we going to say to this i don't know what to call it maybe explore recipe explorer recipe will do and close all right so now one more click on a product we want to go to the recipe page with the project 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're obviously going to need to create the recipe page which is going to be here so recipe.e ejs we're going to have to have so let's say recipe for now uh 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'll change it so let's this is gonna 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 um we're not gonna need a limit here because we're only grabbing one uh obviously we're gonna use the recipe model and we need to change the query 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 restore 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 the home page 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 reg.params so let's do let recipe id id equals reg dot rams 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 gonna do const recipe equals await and then recipe find by id this time and then we're gonna 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 as 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 have a look let's refresh click on an 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.ejs we might as well build the whole page and what we can do is let's start with djs so if recipe [Music] is not equals no maybe then we can close uh or if it's not it goes empty uh we have to try this and then close okay this is our if statement and we're closing everything everything else is gonna be inside here so if this works we're going to say h1 works let's test it and we're getting an error 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 gonna grab some breadcrumbs from was it categories i'm gonna 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 uh 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 dgs put dash and then close egs 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 uh let's create a row for this one div class of row like so and inside here we're gonna create a couple of columns so we're going to have a first column for the product image so leave with a class of code 12 when we're mobile we want it to be full width and then we want call middle to be 4. 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 uh sticky top is just nice to have it will 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 will see what's going to happen probably do need a note so let's put an old tag and just put recipe dot name video tag and we put and let's put loading lazy lazy like so and that's it for the image all right for the next bit we're gonna have kind of like the information of the recipe so let's do another column of this with the class name of call dash 12 co medium 8 and this is going to have a row that's a row and this is going to have a class sorry another div with the class of co 12. so we're creating another column and inside this column create an h1 with the recipe name so it's nicely displayed then i'm going to create another column here this class of code 12 medium i don't really know and if you remember early in this tutorial we added bootstrap icons so i'm gonna use one in here so i so i'm gonna add an icon here so this is gonna be i with a class of bootstrap icon bootstrap icons tag made just to make it look nice and i'm going to put sure 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 div with the class name of code 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 uh between the lines when we set into the database all of the text might be cramped i might i'll show you in a second if i can find an example and i think that's gonna solve the problem and then here let's put like i don't know h4 or something and let's do cookie instructions instructions then let's put the recipe uh description what else do we need we need the ingredients but for the ingredients i'm thinking of creating another row where is this from okay i'm going to create another row inside here so this is going to be diff with the class name of row but in top form and we're going to do another div inside here with the class name of uh co 12. uh inside here we're going to put f sorry h4 ingredients and for the ingredients we're gonna have to put an ordered list now let me show you what i'm gonna do here because the ingredients themselves actual array actually want to display them one by one in the list and in order to do that i'm gonna have to do a for region here so a little bit of work but it's gonna be nice so this url is gonna 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 djs come on start djs and then recipe dot ingredient and then we're going to do 4 page and then function oops 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 ejs here because we're looping we need to open ejs here closer with the two brackets so [Music] curly bracket and normal bracket close ejs 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 let's sound like [Music] 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 uh open it and close the i keep forgetting this [Music] uh else do we need yeah we need a curly bracket we need to put a message from azure so no item found okay hopefully if i've done this correctly we should go back [Music] 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 it uh cooking instructions uh 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 brush to be a bit smaller this is what i've done 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 uh 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 uh 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 uh first of all let's find the category page and change this a little bit so let me open it categories categories 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 oh those images are too small okay ignore this ignore this nobody saw this i think the images of uh have 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 indians 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 gonna still use the same page and let's go to the route and let's create another category route shall we move over here so you can see let's 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 gonna pass an id just like we did with the recipes uh this route is gonna 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 gonna copy all of this or shall we copy 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 uh categories and then we put uh an id just so we know uh category i 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 reg.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 cause a weight category find and we need to put another filter so we're gonna look for category [Music] and then category id is where we get this from the parameter i'm losing it and okay we need to pass this instead now and let's have a look at how this is gonna 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 off here uh 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 gonna do type of categories not because equals undefined and [Music] categories.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 uh can i do the same from the front page i want to grab kind of like this i'm gonna grab this and see whether we can modify so i want to display this so what i'm gonna do is do exactly the same thing here but we're gonna say where is it we're gonna say category by this what we're passing so we're gonna say if type of category by d is undefined category by the length is equals uh 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 why are not found maybe we need to remove this but that's we'll do it in a second okay that's all working the only thing that is not working now is the oh okay we're looking through the categories again okay we need to look through 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 thai recipes i should have put let me 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're getting 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 um i think i'm going to consider this as dinner potentially you could put the category name here instead but uh that's pretty easy to do with djs as you already know how to do that i'm gonna 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 and we want to post to the search page so search like so and we have can do research should we just do search recipe uh search recipe like so and that's it i think post okay so we need to go to recipe controller and make one uh let's study all this up beautiful we need it around here so i'm gonna copy this paste it this is gonna be post and this is gonna be search uh this is gonna be search and we need to create the search page as well but before that i'm gonna grab this and just render it so i'm going to do a rest.rendering 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 h1 [Music] search all right 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 mail out in the header if you remember we had the form here the form has the method of post and 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 term i think that looked like it's misspelled 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 gonna 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 tab that's how we get the search stuff now if you wanted to do the query it's actually fairly simple we're going to delete 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 uh we can't just search in mongodb that easily we're gonna have to do some magic here so bear with me i'm gonna do some crazy stuff in here let's do text and then we're gonna have another filter in here which is gonna be search and then search term and then uh we're gonna put the diacritic sensitivity to true so that quickly sensitivity true okay bear with me here uh otherwise uh we can't just do a normal career 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 we go to back to mongodb as you can see there is a lot of fields in here so we can't just well we could just put a wildcard 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 create a 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 are name and we need to just put this as uh sorry text like so and we need to pass the description in this case description and then we put this as text oh keep turkey 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 indexing you could potentially do the same thing recipe.index but instead you could do i think it's going to be a dollar sign sorry in double quotes dollar sign asterisk astrix and then it's gonna be text i haven't tried this yet but i think this is how it's gonna work i'm gonna leave it here for you to try if you wish and that's it so let's have a look where this is going to work uh what we can do just for a quick example instead of rendering things let's just do res dot json and we're gonna render the recipe just to see what we get okay so if i okay so if i refresh maybe we want to get salad let's put salad and if i search you'll see that we're getting only one result uh and it's the thai chicken inspired fringe 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.run the search title do whatever you like and we just pass the recipe in here with the dot recipe alright i'm gonna render this [Music] all right we can render this we can go to the search page and build one super quickly now so i'm gonna 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 um 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 v4 search result 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 are we getting the recipes which is good let me search for one more what else do we have curry let's search for curry we're getting only two kerisee thai red chicken soup and thai green curry have a click on one we're getting everything working and now i think we're always getting there some new 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 uh if you wish we can do it all right let's do the explorer latest show random and then we can do the form at the end so to do the explore latest i've done this link as the explorer latest so we're gonna have to do this uh what is it called route here we go so this is gonna be a get route so i'm gonna copy one of them and i'm gonna put it here so this is gonna be explore latest [Music] 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.egs [Music] explore latest oh we've got so many open now okay sorry about that let's close everything uh we're gonna need this anyway so explore latest is get we're gonna need to let's grab this one so we're gonna do explore latest uh this is gonna be get explore latest [Music] for latest and for the query i'm gonna do this from scratch so maybe we do the same as the other ones we just do comes limit number and we put the limit number to be 20 or whatever and then we can do const recipe equals a 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 it 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 no sorry limit and then inside here we put the limit number like so we're 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 paste in here change that now and hopefully that should be it so fast to refresh explore latest and we're getting recipe ingredients for each oh um 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 refresh and if we click on explore latest we're getting the latest products in here and that's it i'm gonna leave this one as done so i'm gonna click on this and it's working all right 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 we go to the route then inside here we can do random recipe i mean ideally i want it to be the same explore random so i'm gonna go back to is it the home page i think it is and just change it to explore [Music] 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 already know how to display that all right let's do it in here so i'm gonna grab all this and i'm gonna put that in here explore explore random suggest ask jason so i'm gonna remove this i'm gonna 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.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 uh make a random number out of it so let random equals math dot flow and then inside here we can do math dot random and then we can do times the count that we're getting from here [Music] 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 it doesn't really matter that much recipe as i'm going to display as 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 json 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 a i could do okay 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 um if you wanted to display this to be completely honest we're gonna have to create a new page to do that and i'm just thinking can we just use the explore latest i'm just gonna do it like that i mean you can display it however you want but let's say i'm going to copy all of this i'm going to create another page and i'm going to call it explore explore on wgs 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.json we just need to rest the render and then run them hopefully this should display a random recipe and no it's not recipe for each recipe yeah we can't use for reach in 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 uh another random one appears i don't want to waste too much time on this because you can start it the way you 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 submitted so we have some meat recipe and we have some meat recipe links so we need to create this page first of all so let's go ahead and do that so i'm gonna do another router here it's gonna be submit recipe and the controller for this one is gonna be submit submit recipe and that's going to be submitted recipe so now we need to create this submit recipe page and let's do it in here [Music] rdjs and then h1 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 gonna be get just to say this is gonna be okay let's go to the controller so let's do in here let's just make sure that we just rendered the page for now so what i'm going to do is grab this now i'm going to grab all this just do like a simple render so let's copy this render here and we're going to render some recipe submit recipe the only thing that i'm going to do is remove this and maybe the submit recipe like so that's it and i need to change the controller this [Music] 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 phone this is gonna 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 div of class of px for py5 my five text center so many classes uh h1 class display dash five and then alt and this is gonna be submit your recipe uh inside here we're gonna have another div with the class of co large six mx auto and inside here we're gonna have a text so this is gonna be with the class name of lead and i'm gonna 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 div with the class name of row and justify content center inside here i'm gonna have a column of eight [Music] and then inside here we're gonna 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 uh one important thing that we need to make sure that we put these the n c e m 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 ok 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 div with the class name of row and gap three if that works and then inside here i'm going to create a div class of code 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 [Music] and this is going to be email let's create an input the input will be the type of email [Music] the name will be email the id doesn't email so what's important here is the name we're gonna be grabbing the input information using this name here so you can name it whatever you like but you need to remember that and then we can do the same for the rest so i'm gonna do uh name and then recipe name and then i'm just gonna put name everywhere except this type needs to be text and we're done the next one would be the description so let's add that [Music] description type of text absolutely fine actually the description needs to be text area now okay text area name description id description cause 30 rows let's go for four and remove this because we're gonna be adding a bit more for the description that's why now let's copy this for the next one which is the ingredient and then for this maybe we can do a little example br and we can do small example i don't know ice to other let's just put ice ice then we're going gonna have the input which will be called ingredient with small eye it's gonna have the id of ingredients actually we're gonna remove this because i'm gonna show you something in a second and 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 an ugly one but who cares for now div class of call 12 for the button and then let's do a bootstrap button so button we're gonna do type or button then we're gonna 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 here and we're gonna have to do this on the front end with javascript so let's call this one at ingredients ptn and i'm gonna put plus ingredient ingredient one okay all right we might have to rub this in a diff so we can easily grab it and duplicate it so what i'm gonna do is let's put a div here with the class name of ingredient list okay let's wrap everything in here and i'm going to put one more div 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 to have margin bottom 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 div with the class name of code 12. uh 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 [Music] select form control the name is going to be category [Music] area label is going to be category like so then inside the select obviously we're going to have to put some options [Music] this one is going to be the selected one and i'm just going to put select category and then let's put some more options so this one is going to be with the value of thai if you remember when we did our 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 gonna work it's gonna say an error it's gonna give you an error so just have that in mind and that's why uh we've put it in here otherwise this could be hacked uh 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 gonna have thai and then we're gonna have how many more one two one two three four i think so this one is gonna be american this one is going to be chinese this one is going to be mexican [Music] and this one is going to be indian cool that's then for the options uh what else do we have we have select image this is going to be slightly different as well so let's create another div with a class of co-12 and this is going to be a label for image product image and then this is going to be an input but slightly different input this is going to be a type of file and this one is going to have the class of form control and it's gonna have the name of image and we're gonna have accept and here we can put what we want to accept i'm gonna 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 say accept all and last we're going to create a button so div with a class of call 12 and i'm gonna do a button with type of submit [Music] and then this is gonna have the class of ptn vtn primary and i'm gonna say submit recipe like so let me just double check something text area i didn't add the class to text so this is what i wanted to check so class it's gonna be phone 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 glasses maybe on them so let me have a look super quickly sorry about that is probably the form control class so if i go to the top input yeah okay class form control [Music] 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 some media recipe and we have all of these things now the ingredients doesn't seem to be working so ingredients ingredients ingredients it's going to be this one here foam control and that's it before we do anything we might have to wire this up we're gonna have to do some javascript in order to be able to copy this so we can add more like sugar eyes whatever and yeah let's do that so first of all we're gonna have to go to our main layout and have a look at whether we have a custom js file which we don't so if i do view web i'm gonna put a custom javascript in here so i'm gonna do a script with the source and the source will be slash js which is going to be your public folder and inside here i'm going to put a script so this is going to be script.js and i'm going to try this straight away so i'm going to create this script js and let's save this and one thing i can do oops 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 hello 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 on the press of this button here with the id of add ingredient button so this is going to be an interesting one uh i'm pretty sure that it's so easy to do with the frameworks but uh with pure javascript it's 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 at ingredient btn it's here uh at ingredients btn i can even copy if you wish don't need that so adding region b btn ec 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 sequels document dot query selector because this is a what is it a class name uh i'm gonna have to do with a query selector now i'm gonna have to grab the div is one here so let's do let uh ingredient div equals document i wish bootstrap 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 div object by doing this it's gonna make sense in a second so what i have to do now is do the on click embed listener and i can do it on this button so if we do add ingredient button and then add event listener this is going to be a click uh this is going to function and then inside here we're going to do some magic first of all we need to clone this ingredient dip so to do this let's do let new ingredients equals ingredient div dot clone clone node is the one i need and then that should be set to true and then we need uh 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 going to do let input equals new ingredients dot get element by sorry this one is going to 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 this to the ingredient list 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 add in more ingredients which is what we want i'm not gonna do the reverse now i take him 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 uh 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 earlier 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 it comes equals require and we are requiring the express sessions express session sorry and then we need the cookie passes so const cookie parser 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 uh 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 pacific tutorial on this as well if you want to check it out but i'll explain as much as i can 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 going to do cookie pasta and this is going to accept first of all we need to put something secure here so cooking box secure very secure uh close this and then we need to do app.use and then we need to put a session and inside here we can pass a free options actually the first one is secret and we just need to put something secret so let's put [Music] secret session and save initialize we need to put as true [Music] and the last thing that we need to put is uh resave we need to put ash through as well and we also need to do app.use flash like so and file uploader app dot use file uploader [Music] 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 right sorry so if we go i'm gonna remove this now i'm gonna 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 wrote a 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 what i'm going to create it so i'm going to copy this and i'm going to start with post so my recipe submit recipe yeah that's correct i'm going to 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 going to use the flash messages and that's it i think this 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's so good i click post and we're getting submit recipe cannot post okay uh 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 [Music] and for some reason this doesn't seem to be working now uh 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 summer recipe and we submit as you can see it refreshed and nothing happened so the submit is now working that's all we need we just need 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 and all 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 arrows object in for info areas object like so and this is going to hold all the errors that we want to display to the user so what we can do and to use flash messages we can do rec dot flash and then we can give it a name so info arrows is what i want so this is gonna be for drs but i want one more for the success messages and this could be info submit submit object and this could be wrecked or flash and then info maybe submit and and in order to be able to pass this to the actual page we're gonna have to just pass them one by one here so we can do info errors object and it will submit object just like so now obviously they are empty at the moment but what we can do for 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 gonna go here and we're gonna do rec dot flash message uh like this like reg dot flash and then we're gonna put the message that we want to flash so this is gonna be the info submit message and then in here we can pass whatever we like an object or even a string so i'm gonna write something quickly recipe has been added like so and i'm gonna leave it obviously we're gonna 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 i'm gonna grab that i'm gonna 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 djs i can do if input 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 i might as well do that now so i'm gonna do uh 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 alert 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 it 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 a dummy data first of all and on submit so this is on submit so this is where we're gonna be doing the submission and let's do the usual so we're gonna 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 errors so what i'm going to do is i'm going to grab this uh i'm going to do reg.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 to add a new document we can do const maybe we can do a new recipe and this will be equals new recipe which is our model here at the top so i'm gonna grab that i don't need to do that but i just wanted to show you so i'm gonna grab that new recipe and then inside here is where we add the data so what i'm gonna do now let me close this what i'm gonna 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 gonna add some dummy stuff need chocolate cake then let's do description and then we're gonna do [Music] then we can do email for the email we're gonna do [Music] hello rally.com uk for the ingredient [Music] we're gonna do uh water and for the image not for the category if you remember the only categories that we can use from the enum here are thai american chinese mexican and indian so i'm gonna do mexican and then let's do image and the image i'm just gonna pass an image that is already in the uploads folder let's have a look if we have any i have any okay i'm gonna grab this one here so let's grab the name [Music] 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 a weight 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 um obviously this is dummy data so on submit it's gonna save if it fails it's gonna go here and it's gonna display an error we have to do the same thing for the error here so we're gonna have to do the same thing but it's gonna be info uh what is a sorry info error object so info arrow object inferior object and this is gonna be a danger thing and that would be it 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 oopsy 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 in the database we'll see somewhere at the bottom i believe uh here it is new chocolate cake cool now if we did uh have an error let's say we didn't feel 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 uh giving us like a an error object which we can play with here so what i'm going to do just to show you [Music] rec.json i'm going display jason and i'm gonna put this inside the json here and display so this is gonna make a lot of sense in a second so i'm gonna submit oh it's not rest it's rare sorry it's not rec it's rest jason i thought straight away okay here it is so i submit uh errors name name and message this field is required so it's realized that this name dispute is required and now potentially we could use this to display it oopsie it's so zoomed in to uh display in our form here uh 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 arrow 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 [Music] did they remove the i think i did okay refresh did i not save it uh 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 okay recipe validation field name this build is required so this is the laziest way and if we haven't submitted the the rest obviously he'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 while if we do it with uh javascript on the front end it's nice for the user experience but it can be disabled and i just wanted to show you uh in forms you can get somewhere in phones validation if you wanted to do that i think it would be nice to do that but it's just going to take too much time now uh you need to basically follow this form you can maybe copy it uh i think on the form you need to include needs validation um 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 request and the browser will handle this so if i go back and if i submit look at this this build this build is required anyone let me 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 by this point we can just replace all this uh 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 i totally forgot um okay so for this basically to get the data from the form we're just gonna do rec dot uh body [Music] 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 going to copy this now and just you know what i'm going to paste it everywhere and hopefully change it okay we don't want the name everywhere so i'm going to put a description here email here ingredients here category here and for the image let's leave it for last uh everything else is looking cool so hopefully if we refresh this and input something so hello ready new recipe from form and then we can just do a description we need some ice we need some water and we need some sugar okay category let's put a stye image we're not going to 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 it's 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 built the form now sorry the upload the upload image i'm going to quickly build that now as well uh i do have a detailed video on this but let's just build it inside here super quickly it's not going to be reusable or anything like that let uh image a profile 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's 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 dot files or [Music] object dot keys rec dot files uh it makes sense in a second and then we need to check for the length sequence equals zero then this is gonna fail it's gonna say that no files were uploaded so we can maybe cancel log something log and we can just say no now files were uploaded else oops let's close this uh else we can do [Music] we need to get the name of the input so image upload file is going to be equals reg.files and then this is going to be equals image i think i can't remember when this image now excuse me submit and 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 going to 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 uploads 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 mv uploads to the upper path that we just put and this is going to be a function and it's going to have an error and if we do have an error we can just check if error and then return actually return rest.status and then 500 dot send error okay so what we have to do now is replace this with the new image name uh 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 [Music] new recipe with image sugar we can add more sugar sugar then chinese then we upload an image i'm going to upload my logo here it's a bit recipe has been submitted if we go back uh 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 going to show you the query but 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 cover 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 typing 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 into a try catch just like we've done everywhere pretty much and for the try we're gonna say const response equals a weight and this is what we do our query and the query will be recipe recipe because we want to update a 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 going to 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 going to 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 so name and then maybe we can put a new recipe updated like so let's close this [Music] let me close this as well we can't display the number of documents matched so we could do the response and then n and that is from the official documentation this says this will be [Music] number of documents matched and then we can do res dot n modified and this will display the number of documents modified okay i'm not going to do anything else here for the error we could just console.log something [Music] let's just cancel out 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 he's gonna keep updating the recipe right technically speaking if i was to refresh now you will see that we're getting 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 going to 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 going to be exactly the same i'm just going to remove this so we're going to do contrast and in fact we don't even need this so let's remove this so i'm gonna do a weight 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 going to remove 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 [Music] delete recipe and i'm gonna put a comment 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 rally the brand and i will see you in the next tutorial
Info
Channel: RaddyTheBrand
Views: 4,973
Rating: undefined out of 5
Keywords: nodejs, node.js, mongodb, crud, mongoose, connect-flash, connect flash, dotenv, ejs, express, express-ejs-layouts, express-fileupload, express-session, mongoose node js tutorial, mongoose node js express, mongoose node js, node js tutorial, nodejs database, mongodb tutorial, bootstrap, website development tutorial, backend development, html5 tutorial, css tutorial, bootstrap 5, bootstrap tutorial, node.js upload image, node js project, node js project ideas, node js projects for portfolio
Id: OEdPH4fV7vY
Channel Id: undefined
Length: 186min 58sec (11218 seconds)
Published: Thu Sep 30 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.