Image Upload to Cloudinary - Creating a Product | React and Node.js Ecommerce

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up everyone so in the last episode i showed you how to add these nested routes using react router dom version 6 and in this episode i want to show you how you can actually create a product and even do image approach using react node.js and also a platform called cloudinary so let me show you a demo of how these works so right here we can choose a file so we choose an image and i'll go with iphone 12 here open and then you'll see the name of the file there and the preview of the image right here and then we can select the blend that will be iphone we give it a name so i'll say iphone 12 and then we give it a price that amount and then a description so we can say maybe it's a 6.5 inch display and then we just hit submit so hit submit it's submitting and once it's done product was successfully created and once we come to our home we'll be able to see iphone 12 right here 6.5 inch display and the amount there pretty nice and we can go ahead and edit cut and we can see it right here we can increase cut quantity and do the rest check out and so on so yeah in this video we are going to focus on uh how we can actually create a product so that image will be saved in crowdinary and here it is it's loading there and also we'll have a record of the same in the database so if i refresh here we'll be able to see the record of that iphone 12 in our products correction if we scroll down here here it is so yeah let's just get started and if you're not aware this video is a continuation of my uh complete shopping cart series here on youtube so i'll leave a link to the series at the description section below and also a link um to the source code of this entire project at the description section below so the first thing that we would want to do is to create a model for our product so on our code base we can just go to where we had models so let me expand backend here then modules then right here we can add the product model and for the product model we will bring in mongoose and then we will start by creating a schema so we use a new mongoose here and we have the schema class we invoke that and the first thing that we'll have is a name for our product the type should be string and these will be required so we pass required to true then i can just duplicate these for brand description price and image and then let's just go one by one and edit them so for brand right here type will be string required true then we will have description i'll just say desk type string required true let's have price type will be number are required true then finally here we will have an image for the image our include type is object because we'll be having several properties for the image and then also to know when the product was created or updated we can include our timestamps right here and we set that one to true then down here we can go ahead and const product and whatever we will do we will set mongoose dot model to be product and then we include our product schema right here and we need to export our model now so exports dot product will be equal to our product cool now the next thing that we can do is to configure a crowdinary so first configure crowd inauri um we will come to utils and we can create a new file i'll call it cloudinary and then i'll say dot js from this file we should bring in the dot e and v because we will be reading some environment variables so dot env and we will set these to require dot emv module another thing we should install cloudinari so i'll just bring this up then you can open a new terminal from here new terminal etc then cd into backend then npm i cloudinari so as that installs we can bring in our cloudinary module in here and then right here we will configure our dot emv so dot emv dot config before we do anything else so what i'll do right here i'll just say red const crowdinary um so this object will come from crowdinary and then dot v2 and now we can now make use of this object down here to configure crowdinary so i can say ordinary.config and for this we will be needing several staff we'll be needing the uh crowded name so cloud name they should be set like these like from the documentation itself actually i should have invoked this one like these so wrap this one with those brackets and then pass an object in here then we'll have cloud name and then we'll have api underscore key and then we will have api underscore secret so for cloud name we will read all these from the environment variables so process dot e and v and then dot cloud dinary name so coronary api key and uh corrodinary api secret and i include a comma here so this is how we can like configure it and right here whatever our export is our crowdinary object right there so right here i'll say module dot exports and i'll say crowdinary so now we need to get the cloud dinner name the api key and also the secret from our crowd nerd platform so what you can do you can go ahead and create an account go to crowdinary.com create an account it's free and once you do that you can come to settings and from settings uh once you scroll down here you'll be able to see crowdinary name right here okay crowdinary crowd name right there and then you can come to security and from security you scroll down you'll be able to see the api key here so you can like copy that and we can set up these in our tmv file okay so i'll set crowdinary name here to java charts and then we will have crowdenry api key this will be equal to whatever i copied and then we will also have a crowdinary api secret so for the api secret that should be this one when you click it it will display it and then you can like copy that so i write these up to the very end with the space because uh once you don't include that space it's not copying then [Music] you can paste it here make sure you remove that space okay cool so i have included the name the apik and the secret don't use mine because i'll definitely regenerate them so just do your thing and now the next thing that we can do is to create a route for us to actually create the product and also make use of these crowdenary setup so now we need to create a route for our product so right here at the routes i'll just add a new file i'll say products and then yes so first of all we bring in express and then right here i can say const router will be equal to express dot router cool and then let's export these router at the bottom and then we can make use of this router to create our different endpoints so the first endpoint will be for our posts so we can like include a comment uh this will be to create a product so we'll say router dot posts and the path will be there like the root and then we will have a function here with access to request and response this will be an arrow function and we can do everything in here since we will be performing some async request i can make this function to be an async function now the first thing i'll extract are the properties for our product from the request body so i'll get the name the brand also i'll get the description i'll get the price and also the image from requests dot body okay and then down here uh the first thing that we will do before we even like save the product in the database is to upload the image to crowdinary so right here i'll have a try and catch brock and in here i'll say if the image actually exists from the request body then the next step that we will do is to approach that image to crowdenry so we should bring in crowdinary from our configuration here so i'll say constructor um will be equal to require and this will come from our utils folder and stroke crowding so right here say await so this will be um an async request so i'll say await crowd gnary dot we have an object called uploader then we have a method called upload so this is like provided by crowdinary and then the first parameter that we should pass right here is the image so i'll pass the image so this will be a base64 image and i'll show you how to like convert it from the front end and make it to base64 and then uh the next thing is to specify what we call upload a preset and the upload preset for my case will be online shop online uh hyphen shop so let me show you how to set up your upload preset so if you go to crowdinary you scroll back up you'll see right here we have upload you click on upload then when you scroll down here you'll see that we have upload presets but now you can like add your own so you can go ahead and add upload preset you give it a name so i don't know i'll say maybe online shop without the hyphen and then uh you can give a folder here online shop then that's all just go ahead and save so once you save that upload preset will be listed there and then the name will be online shop so that name is the one that you should include right here and once you like upload the images they'll appear in a folder called online shop at our media library like this one so i won't like repeat all that so now that you get it i just do that and include the name here then once the image is successfully uploaded then we'll have a response here and we can stop that response right here so we will call it uh uproad rest or response so this upper address is actually the details for our image it will be an object so that object will include the wheel the height of the image the url to that particular image and so on so once this is successful i'll go ahead and perform another check here so if upload response exist then we'll go ahead and we will create our product and save it to the database so right here i'll say red const product be equal to new so right here i'll use our a product model so i'll click that to import it from the models so i invoke it and pass the details for this particular product okay and we will have the name so i have already structured them and since the key and value pair are the same so i'll just list them so we'll have name we'll have brand then we will have the description then we will have the price then we will have the image now for the image in this case it will be equal to our upload response right here and that is why i wanted to make sure that it exists even before we include it here okay so from here you can go ahead and save this product to the db so i'll say const saved product will be equal to await then we'll have product dot save and then we can send this saved product to the user so our series dot status and then uh this will now be okay like successful and then we send our saved product so i'll save to auto format this and minimize this one so this is what we have so in case we have an error in all this we should like you know uh log that error to the console and also send a response to the current as well and then we will say res dot status 500 and that means it's a server error and then dot send the error and i'll save and this is how we can like successfully create a product and also save that image to crowdinary okay now we should also have another route for getting our product from the db so this one will be easy so right here we can have a router dot get and we should have the path which will be that the second one will be an async here and requests response and whatever we will do right here is just a const products will be equal to await our product dot find and that will get all our products in the db and we can actually go ahead and send them to the client so s dot uh status 200 and then uh dot send and we will send our products now we should include these in a try and catch brock just in case of anything so i'll say try and i'll move these two lines in here then we'll have catch we have error and we can send the error to the user like this and also you can log it the console optionary so i'll save that so in our index.js we should add it here so right here we will have stroke api stroke products and we should bring it in um right here so i'll actually duplicate this one all right here we have products and now right here i'll say product route so you can just call it products but we have another product here which was getting the data from a static json file so to avoid you know the the same name i'm using products route then right here instead of products i'll say product route so i'll save that so now when we run our app currently this is what we have and we had already created these uh nested routes from the last episode okay and uh yeah we already have a component for create product but it doesn't have anything so we will create the form and then we will proceed to like upload the image and make the http request okay so let's just do that now if you are following this from the last episode um we created these files and uh i'm not focusing too much on the styles so i have copied these styles actually from github so i have all the source code at github and i'll give you access at the description section below so the first thing that i'll do is to just align these create and products are nicely and for that i have this file called common styled and i have two styled components from here the admin headers which is just a display of flex and justify content of space between it's just a div and for that in our products file you can just make use of it right here so i'll say admin headers and now that will come from that file and then for the button actually this one is not complete and then for this button i'll make use of this primary button so instead of button i'll say primary uh button right here also complete it right here and now when i save you'll see that these are now nicely arranged but we have this great product which is not so for that uh i'll include it outside the admin headers so i should have these fragments still and i'll take that there then include the outreach outside the admin headers and when we do that now this is right here so when we go to products initially here we can have like a table to manage our products and so on but then we can create a product using this button and now let's go ahead and create the form for creating a product so in our create product right here uh we have this our style create product so instead of just create product i'll make use of that so i say styled create product and what this will do is that it will justify our items and our items is the styled form and also the image preview so that they'll be um in side by side okay so in here i remove that and we should have two things the styled form like that and also the image preview so image preview like that okay and these are the styles let me scroll down here these are the styles for the styled form you can like post and type them out and then these are the styles for the image preview pretty nice now let's start with the styled form right here so this is just a form a number one you see form okay that is how like spelled components work if you haven't worked with it before so right here we can include the different inputs and also a submit button so first of all i'll actually add a h2 a h3 that is and i'll say let's create a product and then after this we will have an input field and the first input field will actually be for uploading an image and these will accept several staff first of all the type will be file and then we have other attributes for example we have an accept attribute which we can specify what kind of files do we want to upload are they documents pdfs or images so in this case i only want images so you can say image and then forward slash and this will accept all the images but will not accept documents like pdf or text files or any other file okay and right here we can create a piece of state for uploading this image so right here let me have a piece of state i'll say const product image and set product image these to be equal to use state and this will come from react obviously initially these will be just an empty string now right here we will have an unchanged event so let's say on change and this unchanged event will call handle product image uh upload so it will call a function called handle product image upload so we don't have that function let's go ahead and create it so i'll say const handle we will have access to the event and we can read the file that we are trying to upload from this event and first of all fix this error right here so right here how can we do that so we'll say const file uh will be equal to e dot target and then dot files and this usually displays it in form of an array and therefore we can get the first object which is actually our file so let's see if this is working so i can like log these to the console so all we have done is to make sure that this is type file then we include what we want to accept then we have an unchanged event uh which we can use to like you know run this function and we get the fire from the event so i'll come to the browser and now you see we have this uh nice input right here with choose file currently we don't have any file choosing and let's open the console so that we see if we can like select a file so i'll go ahead and click on choose file then i'll select iphone 12 here and open once we open you can see we have the file right here as an object so we are able to select the file so we have the name the size the type etc now we can be able to transform this file into uh what we call base64 file and uh this is how we can do it so after we like read the file we can call a function right here and i'll call this function transform file so let's actually first create it so right here i'll say const transform uh file will be equal to here we will receive the file and we will do something in here so right here we record our transform file and we pass in the file right here so we have a class in javascript called the file reader and we can like get an object from that so i'll say red reader so right here say const reader to be equal to new fire reader right here and we invoke that so this reader is the one that will have a strike you know uh get the images a url like um a basics for url so instead of an object so what we will do we'll say if fire actually exists what we will do we will go ahead and use our reader and we will say dot read as data url this is a method that already exists and then we will just pass our file right here okay and then right here we will record reader dot on load end so this is like um how can i call it an event which will be fired after it has completed like reading the file okay so once it completes we can set this to be equal to an arrow function and we can be able now to like update our state here so i'll simply call a set product image to be the result reader dot result so what have we done whatever we have done is that we have made use of these class for a reader to read the image as a url or a string and then we like update the state once it has completed reading that particular file and then else so right here if we don't have a file or whatever we will do we just try to set the product right here back to default so this can happen whenever you like you know open the popup and then cancel it so it will like reset this to default so yeah now what i can do i can just like lock this product image the console so i'll say console.log of our a product image i'll save and then let's see what we have so our hit refresh and i'll click on choose file and i'll then click any file here open and now look this is now our image in form of a string right here and it's a base 64. pretty nice and this is what we will be uploading to crowdinary now we can also like display it directly right here so let me show you how to do that so at our image preview we can say if product image actually exists what we want to do is uh to display an image else we can show a message image preview will appear here and then right here now we can just use the image tag normally that is img the source will be equal to our product image from state and then art uh i don't know i'll say image or product image and then i can just cross this i'll save so you can see we are like just including this from state and let's see look we have that image right there the one that we selected and we can choose another one open and look it changes to that and once we open this and cancel it will like you know uh reset the state so it will it will do this it will set it to nothing and there we go so we are able to like select the image and store it in state now the next thing is to set up these other input fields so right here we'll have another input the type will be text and we can like actually perform basic you know uh form variation of required in each of them so i'll say required to this one as well and now for this one let it have a placeholder of name and then we will also have an unchanged event we will have the event here and we require set name and we'll set this one to e dot target a dot value so we don't have this set name so let's set up part one i'll just go ahead and duplicate these several times so all of these can be strings and down here i'll save to auto format this one and then i can duplicate it down here now we can have i'll say name there and now this one can be price and then we will set price let's duplicate this one and we'll set it to description so this creation actually can just say short then these will be set desk so we don't have one for selecting the brand i can set that to come after the image and these we will make use of the select tag okay and we can have an unchanged the unchanged will be just similar to this one so i'll copy that then paste it here the only difference is that we will have here is set brand okay and we can also make it to be required and then now right here we can set the different options so i can have an option tag the first one will be select brand and the value will be an empty string so that will not have a value so what i'll do i'll just duplicate these for iphone or samsung xiaomi other okay cool so yeah we have our form there uh we need a submit button and i can make use of the primary button right here so i'll say primary button and then we include the text here submit cool so let's see so we have our form right there cool now we need to make the http request and for that we'll be making use of redux so we already have the products right actually so we don't need to create another one and we have one where we are fetching the data so we just add another one for posting the data so right here let's go ahead and add an action creator so what i'll do and actually like duplicate this one to make my work easier and whatever i'll do is that i'll have our products create okay we create an async tanker and right here we have products we give it a name so this will be are create then we perform a http request now right here we'll be receiving values from the form so these values will represent an object that is coming from our form whenever we submit it then here we will have axios dot post and we will post to our base url so if i check at the api here we have this url which is our base url so that is what we'll make use of right here so i'll make use of backtracks url right there this will come from the that these file slice this one okay and then uh we can now like append stroke products and the second parameter is our values so right here i'll say values so once that is successful we will return a response dot data and then we can like log the error to the console also right here we can post an error message so toasts dot error and whatever i'll say is error dot response then use these dot data to make sure that we say free right credit so at the top uh let me bring in that to sell import toast chrome react justify save to auto format and then let's handle the state so i'll just duplicate these ones and i'll include one for the status for like creating a product so i'll say create status initially to be null and then now we can be able to handle those statuses right here so i'll change products fetch all the products fetch here to products create okay if it's pending if the status is pending then the status here dot create will be pending so i can highlight these and then use ctrl d uh two more times so that i can update these to create status so this is fine and then for this one dot items dot push so we will push our product from the api to the array so [Music] i'll cut this and paste it in here now to wrap this up we need to dispatch these products create at our create product at our styled form we will have on submit event and we will set it to be equal to under submit let's create that so we'll say const handle submit will be equal to an arrow function here and we will have access to event and then we will prevent the form from causing page reload so prevent default and then now right here we should perform the dispatch to perform the dispatch we should bring in the use dispatch so i'll say import use dispatch these from will come from react redux so from react redux we initialize it const dispatch equal to use dispatch we invoke part and now let's perform a dispatch so right here i'll say dispatch we invoke this and whatever we are dispatching is our products are create so i'll click on this one to auto import it we invoke it it's expecting values and the values should be an object the object is having the name it's having the brand it's having the price it's having the description and also it's having the image so for the image it will be equal to our product image so the rest key and values are the same so name will be the name from the state brand from the state all these are the same key and values but for the image the can value is different so we specify that so i'll save and now we are performing the dispatch and let's test this one out fingers crossed let's come here uh i'll hit refresh to make sure that everything is refreshed choose a file i'll go with iphone 12 i'll open that i'll select the brand to be iphone then i'll say iphone 12 pro then i'll select the price super expensive here then a description i'll go with six pointer for display and then i'll hit submit and see what happens so submit it's taking time and we get an error internal server error request field and let's see our backend uh see what error we have so i'll scroll here for node um request dot status code is not a function okay at our api so i'll go to backend routes then the products route and uh rain 29 i think we made uh we made use of request instead of uh response so this should be less and then dot status uh 200 and then dot send our saved product and actually since this is coming uh right here uh that means that we have already like saved it to the db and uh this is the point that it failed so we should have actually like uploaded the image and saved it to the db so let's like check it out so i'll come here to the online shop and yeah it created this iphone 12 pro to the uh media everybody and also i think it saved it to the db so if i come here and let's refresh right now we don't have products let's refresh and see so now we have products and once we check at this you'll see that it's there 6.4 display and name is iphone 12 pro so it's actually like working the only issue was to send this to the user okay this this is only the issue so it's it's working cool that is good now um the next thing will be to get that from the database like make uh these requests for getting it from the db and show it on the ui so right now whatever we are showing is our dummy products so this is hard coded in a json file which is right here okay this one this is the hardcoded json file but right now i want it to be dynamic since we can be able to add the product in the db let's make a request to get those products from the db so in our products rice we already have this products fetch and all we need to do is to change the url here and i'll change that to be this one right here so i'll copy that and paste it here and yeah now another thing is that once we go to home right here uh we had another request so this was using rtk query so we had two ways of fetching the data we had these products api which was using rtk query and also we have these uh which is using creator sync func so i want to transform this to make use of the creator sync bank and for that uh we will make use of this right here so i'll change these products uh i'll change the items here to data now that data will be mapped down here okay and i can comment this one out also remember we are already dispatching this particular action creator this products fetch if you go to index.js i think yeah this is why you are performing the dispatch of the products fetch action creator okay and then once you do that it will fetch the data and that data is available instead and you can get it from state uh just like this you make use of the user selector hook and you store it there now another issue that we will have is that now this product coming from db is making use of underscore id so instead of id you should change this to underscore id and we should do the same at the cart so if you go to cut right here okay right here sorry change this one to underscore id and then once i do that another issue that we have is that in our cuts rise we should change that to underscore id so in cuts rise we had [Music] this payroll.id we should change everything to underscore id so i have i write that dot id use ctrl d to highlight all of them then i'll bring it at the front here and use underscore dot underscore id for everything to work out so i'll save that okay now when i come back um is roading is not defined at home so i'll come back to home and is roading why is zero is loading okay this one so i'll just remove it and save uh once i save let me refresh okay cool now rook we can be able to load these data from the database but we can see the image so to fix that we need to go to uh where we have home and now instead of having the product dot image we will have product dot image dot url remember now image is an object okay and if you check at the database we have image object but we have the url down here this one and also we have the secure url you can use any now if we check it's rolling that particular image pretty nice so uh if we can't cut um now all this doesn't exist so i'll clear the cut and let's try to add this one to cut so i'll go ahead and add cut it's added to cart but in our shopping cart we can see the image so let's go to the cart again and make sure that we change the cart item dot image to cut item dot image dot url sorry save that and yeah now we can see the image and can we increase yes we can increase we can decrease and we can remove so now it's working cool i know it have been a bit of a process but this is how as an admin you can create a product using this form and also using crowdenary and also mongodb database now the next thing that i'll show you is that uh how you can actually protect this route to make sure only the admin can actually like make the request and also to make sure that uh only a logged in user can make that request and the reason why i say that is because uh if i log out and uh just visit this url so if i just log out and visit this url if i refresh you'll see that i can still make that request i'm not logged in i'm not an admin but i can create a product so i'll show you how to protect this page and also how to make sure that you have the admin for you to create a product so i'll see you in the next one
Info
Channel: Chaoo Charles
Views: 9,931
Rating: undefined out of 5
Keywords: chaoo charles, chaoocharles, chaoo, charles
Id: YI8MKzAKYCk
Channel Id: undefined
Length: 53min 8sec (3188 seconds)
Published: Tue May 10 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.