React Node.js Video Sharing App Full Tutorial (Redux, JWT, Cookies) | MERN Stack Youtube Clone

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello friends today we are gonna complete our full stack video sharing app using react node.js mongodb and firebase this is the home page it will fed some random videos from mongodb using a backend api we will be able to login or register using this form and also we can log in using a google account to do that we will be implementing google firebase authentication let's click on any video card here and this page shows the video and its details right now we can like or dislike the video we can see all its comments and add a new one and also we can subscribe to any channel in this case if i click on the subscription button here it's gonna bring all the videos of the channels that i have subscribed to and there is a explore button and it brings the most trending videos by the way when we open up any video there will be a recommendation section here and it will suggest the most relevant videos using the tags of the current video and then we will create the search functionality and it will fetch the videos with the same keyword in their titles and finally we will create this popup component and we will be able to upload new videos and all these files will be stored in google firebase storage it's an awesome project where you can learn how to create rest api make complex api requests using cookies provide security using jwt react hooks firebase redux toolkit and more i hope you will like it if you want to see more tutorials like this please like the video if you are ready let's get started okay if you created a new folder let's create our backend server to do that i'm gonna create one more folder here and it's gonna be server or api or whatever you want and inside this server i'm gonna create my express api to do that firstly i should initialize my not application i will come here and say cd server i'm inside this folder right now and i will say npm init and i will say dash y and it's going to create package.json here let's check as you can see it's here and inside this package i'm going to install my dependencies to do that you can use npm install or yarn add and first dependency will be express server and also i'm gonna add nodemon it's gonna allow us to listen our application and finally i will say mongoose so we will be able to connect to the mongodb and make crude operations of course we are gonna install some other libraries but for now i'm gonna install them and it's ready as you can see they are here and i'm gonna create here my index file i will say index.js let's import express if you are using nodejs you are doing this by writing const express require express but i don't want to use this structure it's kinda old as you can see it says it may be converted to as module we are gonna do that and i will say import express and from express but if you do that it's going to give you an error to prevent this i will come here and say type and we are going to use as modules like that i will save and right now everything is okay let's create our application i will say const app and i'm gonna use express function here like that of course to run this application we should listen a port number i will say app dot listen and i'm gonna write here any port number i'm mostly using this number of course you can use any other port numbers but make sure that any other applications are not using that and here i will say console.log connected okay it's ready but how we are gonna run our application i'm gonna use note mod here otherwise for any changes you have to come here and say note index.js but if you run this application with nodemon it's gonna listen our application we are gonna run it once and we won't have to run it again and again let's say start is gonna be our starting script and i will say nodemon in index.js let's try npm start or yarn start as you can see it's connected if i make any changes here it's gonna be immediately in the console let's change this back and right now i'm gonna connect to my db to do that you can go to cloud.mongodb.com and after that you are gonna see this page of course if you don't have any cluster firstly you should create your free cluster you don't have to pay anything it's totally free and after that you are gonna see this page of course there is something important here to reach our db firstly we should create a user here let's say lama and password will be the same as you can see we are able to read and write to any db of course you can add custom rows but we are gonna be an admin i'm gonna create and one more thing i'm gonna click here network and as you can see there is a ip list here if you don't add here any ip you won't be able to read your db i'm gonna click here if you click on this button it's gonna add your computer ip here if you click here you will be able to reach it from any location and any computer of course if you deploy your application you should write here your server ip but we are using localhost it can stay like that it's gonna take a while and i'm gonna go to db again and as you can see there is a connection button here and i'm gonna choose connect your application and as you can see this is gonna be our secret key which includes our username and password i'm gonna use it and let's create here our connect method of course we are gonna need mongoose let's import and i will say const connect and i'm gonna use mongoose and connect method and inside i'm gonna paste my secret url but it's not a good idea to share your connection string here that's because when you share your code on github or any other website everyone can see your username and password to prevent this i'm gonna create here emv file dot env and i'm gonna write my connection string here let's say and this uri of course i'm gonna change this password it's gonna be lama again and i will save but how we are gonna use this mv file to do that we are gonna need one more library i will say yarn add dot env let's import this dot env and i'm gonna make its configuration otherwise it's not gonna work i will say dot me and config we can use it right now i will say process dot env and my variable name which is by the way i forgot here parentheses okay and after that i will say done if everything is okay right here connected to db i will save and if there is any problem i will catch this i will say error just throw this error like that i'm gonna shrink this a little bit okay it's ready i'm gonna copy this function name and call it here then we run our application it's gonna automatically connect to mongodb i'm gonna save and as you can see connected connected to db let's say connected to server like that perfect right now let's create our collections as we did here before as you can see hotels rooms users and let's decide what we are gonna need firstly we are gonna need a user and this user will be a channel at the same time and we are gonna have video collection and comments collection let's create i will come here and create new folder it's gonna be models and first one will be user i'm gonna import mongoose again and i'm gonna create user schema i'll say const user schema and new mongoose and schema and first property will be username and again remember it's gonna be our channel at the same time when we log in we will be able to upload new videos or comments with this channel so i will say type will be string and i will say required and it's gonna be true it's required because we cannot create any user without username and finally i will say unique and it's gonna be true also so nobody can create same user with the same name and one more property and it's gonna be email it's gonna be exactly the same string required and unique let's create one more it's gonna be password required but it doesn't have to be unique what else i'm gonna say image it's not required they don't have to have this image and what else we are going to have subscriber numbers let's say subscribers type will be number and by default when we create our channel it's gonna be zero and one more and it's gonna be subscribe channels or users let's say users and i'll say type and i'm gonna use here an array and in this array we are gonna add all users that we have subscribed so it's going to be string basically then we create our channel it's going to be an empty string when we subscribe in the channel is going to be that channel's user id you can do the same thing here you can say array and string and you can add user ids but we won't need that but because in the video page we are gonna see only channel name and its subscriber numbers but we are gonna need them here that because in the home page we should see videos that belongs are subscribed users that's why we are storing them and i'm gonna write one more thing here and it's gonna be timestamps i'll say true basically it's gonna create creation and updated date of this user okay let's export this i will say export default i'm gonna use mongoose and model and our model name will be user if you check here as you can see users rooms hotels basically when we create any name here it's gonna make it plural and finally i'm gonna write here my schema is going to be user schema like that so let's create others i'm going to copy here and create one more model here it's going to be video of course i'm gonna change this name it's gonna be video and video schema and i'm gonna delete here okay firstly a video should have a user id when we upload any video it's going to add here our user id it's going to be string required i'm going to delete here what else we are going to have video title again string and required video description video image is gonna be our thumbnail and video url we are gonna upload our videos in google storage and we are gonna store here its url and what else we are gonna have video views is gonna be a number and at the beginning default is going to be zero and we can write here video tags i'll say type it's gonna be an array and i will say string if you don't write anything like that let's duplicate this twice and this one will be likes and dislikes comma here and here and that's all i think it's gonna include again user ids who like our videos and dislike our videos and that's all i'm gonna copy here and one more model here and it's gonna be comments let's paste and change its name comment and let's delete them and again we are gonna have a user id and i'm gonna write here which video we are commenting so we are gonna store here video id finally our text let's say description and that's all nothing else we cannot add any image or something to our comments but how we are gonna add new user video and comments to our db to do that we are gonna need our roots let's create one more folder here roots basically we are going to say localhost our port number and api and let's say videos and any video id here when we do that it's gonna fetch all those videos in our db and return their names descriptions images videos whatever so we are gonna need those roots here and finally we are gonna have one more folder here and it's gonna be controllers basically we are going to make all crude operations in these controllers adding new video deleting updating anything is going to be inside this folder so i'm going to close everything here and create my first route and it's going to be users root let's create others also actually videos and comments and here i'm going to create my controllers let's say user video and comment if you have never created any api with express server don't worry you are gonna understand why we are separating them like that just wait i'm gonna close them and let's create here something and you are gonna understand better i'm gonna import express again and i'm gonna create my user router i will say const router and it's gonna be express and router function like that and we are gonna use this router in our index.js basically i'm gonna export this i will say export default and router let's write here any route and i will be able to explain better i will say router get method because we are gonna fetch data and i'm gonna write here any endpoint let's say test and i'm gonna write here my controller function let's create here something i'll say const test function and i will say console.log test is working let's call this function here test of course we should export this i'm gonna call again as you can see it's here i'm gonna enter but before as i said we are gonna define this in our index.js i'm gonna call my user root i will say import user roots you can write here whatever you want because we are exporting as a default and from my user root here roots and users.js so i can use it right now and i will come here and i will say app.use and which endpoint we are gonna use we are using api and after collection name so basically it's gonna be api users and we are gonna use this route by the way there is a mistake somewhere okay i forgot here.js i'm gonna save again okay it's connected let's try i will say api users and test i'm gonna enter it's not gonna return us anything but as you can see test is working so we are able to make any request right now but how we can send here something it's really easy basically we are gonna have here request response basically request is what we are getting from user and this is what we are sending to user let's say response json and i will say it's successful let's see right now as you can see it's here we can send anything to users we are gonna send users we are gonna send videos comments everything it works like that so i'm gonna do same thing for others let's delete this actually we are not gonna need it i'm gonna copy this and paste for comments it's gonna be comments of course we don't have any test yet and videos by the way it's going to be comment not comments and let's define them here i will do exactly the same thing video root and comment root let's use them here video and comment okay i'm gonna delete here and let's think what we are gonna need first firstly we are gonna create a user but i'm not gonna do this here that because authentication is the most important part of an api and i think it should be separated so i'm gonna create here one more route and it's gonna be authentication and let's create controller and again i will copy this and paste here and inside index i'm gonna import this and here let's try it at the beginning by the way ah okay i'm gonna save and that's all i'm gonna close everything and open up my authentication route and i'm gonna write here what requests i want to make firstly i will say create a user it's gonna be sign in and one more is gonna be google authentication that's because in our application we are able to create a user using username email and password and also we will be able to use google authentication and sign in using our google account let's create our routes i will say and it's going to be a post method that because we are sending our information remember username email and password and our endpoint will be sign up and here we are gonna call our controller but we don't have yet we are gonna create and i'm gonna duplicate this and move it here and it's gonna be signing again it will be post we are sending our username and password and one more is gonna be let's say google let's separate them and i'm gonna come here and create my functions now you'll see export const sign up and remember we are taking request from user and sending response to user so how we are gonna create new user to do that of course we are gonna use mongodb basically i'm gonna import mongoose and i'm gonna create my user here of course if you are making any requests to mongodb your function will be async that because it's gonna take a time and here i will try to create a user to do that i'm gonna use try catch block because it can be any error here if there is an error we are going to handle it later let's say to do and i will say const new user and i'm gonna use my user model let's import this here like that and i'm gonna write here its properties like username email and password but how we are gonna take those information we cannot do this in here we cannot send any data to do that we are gonna need a making api application there are many options that you can use postman insomnia vs code rest or others but recently i'm using insomnia i really like this application so we are gonna use it yeah i will come here and create new collection let's say video app and here i'm gonna create new folder i want to make everything well organized so let's say authentication auth i will create and inside this folder let's say new request and it's going to be sign up and remember which method we are using is going to be a post method and i'm going to write here my url localhost api and authentication and how we are gonna send our information i'm gonna come here and choose json and right now i'm able to change any information first one will be name let's say test we are gonna need email let's say test gmail.com and one more is gonna be password like that right now i'm able to send all this information about how i'm gonna take it here remember we have choose body here so it's gonna be request and body and it's gonna take everything that we sent inside body let's actually try i'm gonna comment this out and i will say console.log request and buddy i'm gonna call this function in my router like that let's try i'm gonna send cannot post because i forgot here my endpoint i'm gonna send again as you can see it's not returning anything but here as you can see there is an error we cannot see our username password email that because we didn't allow our application to take any json file from outside to prevent this i'm gonna come here and say app.use express.json i'm gonna save and let's try again i will send and right now as you can see all these informations are here i'm gonna close sidebar as you can see perfect right now we can use them but as you can see we are able to see our password here we cannot store this in this way it's not secure basically we are gonna encrypt this password to do that we are gonna use bcrypt library and it's gonna be pcrypt.js let's import this like that and i'm gonna delete here and open up my try catch block and i will say take everything inside body we are using spread operator here to take every property but i want to change its password but how we are gonna encrypt it let's come here as you can see usage we are going to create assault and hashed password let's do that you are going to understand better right now i will paste here of course we are not going to use var it's going to be const and here i'm gonna write what i want to encrypt it's gonna be request body and password which we sent here and it's gonna hash it and we can use it here it's not gonna be what we sent it's gonna be this hashed password okay we created our new user but how we are gonna save this to mongodb it's really easy i will say new user dot save that's all of course we are gonna use a weight here that because it's an async function and we are making async operation here and finally after saving i will say response status is going to be 200 successful and i will say send or json doesn't matter user has been created let's see i hope everything is okay i'm gonna send as you can see user has been created if i go to mongodb as you can see our db here and users let's check okay perfect it's here and all those properties but if there is an error what we are going to do basically you can say response send and this error but i wanna make more specific error handling to do that we are gonna use one more middleware here i'll see app.use if you watched my previous project you already know but i'm gonna explain again it's not gonna be that deep but i will say error request response and next basically this is how we are handling arrows in xpath server it's a middleware it takes four parameters error request response and next and we can send any specific error to user here firstly i'm gonna define my status my message and i'm gonna send to user const status it's gonna be error dot status and if we don't send any specific status it's to be just 500 one more is going to be message if there is no specific message we will say something went wrong of course not comma semicolon and let's return this to user i will say return response status is gonna be our specific status here and i will say json or send and you can write here whatever you want if you want to you can just send your message but i want to make it a little bit better so i will say success false status again our status and message will be our message of course after as6 we don't have to write them like that if you are using same key and value basically you can write just one of them and it's gonna be exactly the same thing okay right now we can use it everywhere let's come here right now we can use next here and i can use it here let's say next error and i will save right now if i try to sign up with same name and email i will send and as you can see successful status and our message will be duplication error that because we are using same name and email it's that easy but we can make this more specific we can create our own errors i will come here and create one more file here and i will say error and as i said if you want to get more information about error handling and middlewares please watch my previous project manage tag booking application and you are going to get more information there and there are timestamps in the video just check error handling section and watch it let's create our specific error handler i will say const of course it's going to be export we are going to use it everywhere and i will say create error we are going to take a status message and i'm going to create here a new error const error new error and we are going to change its status and message it's going to be our status which we sent here i will do the same thing for message and finally we are going to return this error right now let's say create error and error status let's say 404 not font if i try again as you can see it returns this specific error of course we are not going to use it here it can stay like that it's already clear it says you cannot duplicate name and email so we don't have to write it here and that's all it was our first route and controller i hope you understood if you understood everything by now it's gonna be much easier right now okay let's create other controller here i will duplicate this and it's gonna be sign in let's create our request here new request is gonna be sign in again post i will create and again localhost this url but this time it's going to be signing and inside body again i'm going to choose json and send my name test and password but as you realize we are sending normal password here but in our db this password is hashed so basically we are gonna decode this password first we are gonna compare this user with this user if they are exactly the same user we are gonna return our successful response let's do that firstly i'm gonna delete here and firstly i will try to find our user i will say const user it's gonna be await our user model and i'm gonna use a mongodb method here and it's gonna be find one and i'm gonna write my condition here name will be request body and name basically it's gonna look into user collection try to find one which has a name and it's gonna be test and i can create an error here if there is no user we can send 404 i will say if there is no user return next create error 404 and user not found let's try i'm gonna come here and say test one there is no user like that i'm gonna send oops i forgot writing here my signing function like that i'm gonna save and try again and as you can see usually not found and right now i'm gonna compare my password if it's correct or not i'll say const is correct let's see how we are gonna do this as you can see be crypt compare our password and hash password if it's correct it's going to return true if it's not false i will say pcrypt.js dot compare first one will be what we send request buddy and password and second one will be the password inside our db remember we found this user we can use it user dot password and i will say if it's not correct we are going to return one more error let's copy this and i will say 400 and wrong credentials it's gonna be test again but i'm gonna write wrong password i'm gonna send oops there is something wrong it's a async function i think let's try i will say await and send again and as you can see wrong credentials so what if everything is correct basically we are gonna send our user information but at the same time we are gonna send an access token it's really important guys that because in the future when we try to delete our videos or upload any videos make any comments we are gonna use that access token and we are gonna verify our user but how we are gonna send it basically we are gonna use json web token i will say yarn add json web token let's import this here jwt from json web token and let's create here our token i'll say const token it's gonna be jwt dot sign and you can send here any user information its name its id whatever but make sure that it's a key information that you can verify your user and the best thing is using here user id i will say id it's going to be our user dot id i'm using underscore that because in rdb as you can see underscore id we are gonna use it here basically it's gonna take our id and create a hash token and we are gonna take this token and send to our user after login process and there is one more thing here we should provide any secret key here you can write whatever you want but let's not make this here as you remember we have an emv file here we can write here any secret key let's say jwt and my key will be something like that let's use it here process emv and jwt okay right now we have a token we can send it to user to do that we are gonna use cookies i will say response dot cookie and cookie name will be access token and we are gonna send our token we can write here any configuration let's say http only and it's going to be true and it's going to make our application more secure under third party scripts not will be able to use our cookie and after that i will say status by the way to use cookie we have to import one more library i will say yarn add cookie parser i'm gonna open index and import this and i'm gonna use it somewhere here i will say app.use cookie parser like that okay let's continue 200 successful and we are gonna send this user i will say json like that let's save and see i will try sent okay i forgot changing this it's a correct password right now i will send and as you can see all those informations are here and additionally we have a cookie and this is our hashed access token and remember it includes our user id we are going to use this id to identify our user okay perfect but there's a problem here as you can see it reveals our password even if it's hashed we shouldn't send this password like that to prevent this i'm gonna get rid of my password before sending to user i will say const our user and i will say password and other details basically it's going to separate our user object password and other details everything apart from these passwords so we can send this so i'm gonna copy this and paste here but right now we are gonna have another error let's try i'm gonna send and as you can see it's not exactly an error but it returns us many unnecessary things as you can see our user is still here but we don't need them to prevent this we are gonna use this document and i will come here and say user dot document like that let's try one more time i'm gonna send and as you can see everything is here but password perfect so we've finished our controllers here of course we are gonna sign in with google also but we are gonna do this later that because we are gonna need a google button we cannot send it here using insomnia we are gonna take care of this after installing our client part okay we can sign up we can sign in so we can close this authentication actually i'm gonna close everything and let's take care of users so let's see what we are gonna have i'm gonna paste it here as you can see update late we are gonna get a user we will be able to subscribe any user or unsubscribe we can like a video and dislike a video as a user so let's create our routes i'm gonna write the first one it's gonna be a put method that becomes updating an existing user and my endpoint will be my user id so we are going to specify our user id here and according to this id we will be able to update our user actually let's create them here first updates request response and next i'm gonna delete this and i will create others update delayed get a user subscribe unsubscribe like and dislike i can delete the rest okay i can use them here right now i will say updates let's create others it's gonna be delayed methods again we are gonna use this id get a user it's gonna be a get method but i'm gonna specify an endpoint here and it's to be find it's going to be users find and specific id here subscribe is going to be put again we are going to update our user let's say sub and id and this id will be the id of the channel which we want to subscribe i will do the same thing here unsubscribe like a video let's say video id actually it's clearer and finally dislike okay let's add our controllers it's gonna be delayed okay let's write it here by the way we cannot use blade as a name here i think so let's correct this plate user okay get user subscribe unsubscribe like and dislike like that okay let's use them but there's an error here let's see what's that error delayed user okay plate but there's the important thing here as i said we have to verify our user first if we don't verify any user can update this user or delete or subscribe to any channel using this endpoint but how we are gonna verify our user i'm gonna come here and i will say verify token we are gonna use jwt and i will say export const verify token it's going to be request response and next and we are gonna take the access token from our cookie remember when we sign in we are taking this access token and we can use it here i will say cons token request cookies and access token i will say if there is no token i can return my error i will say return next create error let's import this from error and inside i'm gonna send 401 status which is not authenticated and i'm gonna say you are not authenticated and i will write here one more condition we can have a token but it doesn't mean it's valid so we have to verify this i will say jwt and verify i'm gonna pass here my token and my secret key remember process emb and jwt and this verification function is going to return us either an error or our information remember in the access token we have an user id let's say here user you can write here whatever you want but i prefer using user and i will come here and say if there's an error it means our token is not valid and i'm gonna return one more error here it's gonna be 403 it means okay there is a token but it's not valid so i will say token is not valid okay and if everything is okay we are gonna send this information i will say request and user equals user as i said you can write here whatever you want you can say info you can say data basically we are assigning this jwt object to our request and user so we are able to use this request and user in any api request you are going to understand better right now and i will say if everything is okay we are gonna assign this user and i will say next basically after verification it's gonna continue where we left what i mean by that if i come here and say verify token is going to be our middleware which means whenever we make this api request it's going to go to verify token function and it's going to check if everything is ok it's gonna assign our user id here and we are gonna continue what we want to do in this case we are gonna run this update function and we are gonna update our user let's create this controller and you are going to understand everything better i'm going to come here and write my condition basically i'm going to compare this user id and this jwt id if they are equal it means i'm the owner of this user so i'm able to update it if i try to update other user here using other user's id it's not gonna match with our jwt user id and we are gonna send an error let's do that i will say if request params and id which is this id equal request user dot id remember it comes from jwt and i'm gonna write here my updating operation if they are not equal i'm gonna send an error i'll say return next create error 403 and i will say you can update only your account okay if everything is okay i'm gonna update my user i will say try catch block if there is an error we are gonna send it like that i will say const updated user wait we are going to use user model here that's import models and user again js here don't forget this extension and i will say find by id and update so basically i'm gonna pass in request params and id and i'm gonna find this user and after that i'm gonna update to do that we are using set method and it's gonna be request and buddy and finally we are gonna send this user i will say response status 200 json and updated user by the way again i forgot extension and where else okay i said i wait but i didn't use async here okay perfect let's try i'm gonna come here and create one more folder and it's gonna be user which means channel requests and inside let's say update user it's gonna be a put method i will say localhost users endpoint and here i'm gonna write my user id let's check this user id i'm gonna paste but i'm gonna change this let's add one which means it doesn't belong to me and let's say name is gonna be updated let's send as you can see you can update only your account if i delete this our user will be updated but as you can see it's still test here to prevent this i'm gonna write here one more option and it's gonna be new true basically it's gonna return as the newest version of our user by the way it's not gonna be response of course is gonna be request i'm gonna send as you can see updated if i delete this let me show you one more time that because it was response i'm gonna change here and send as you can see it's not changing but if i say leave true it's gonna be our updated name perfect so it's easier to create others right now i'm gonna copy here and paste for delayed user and again we are gonna compare users if it's not our user i will say you can delete on your account if it's our user we are just going to delete it find by id and delete so we are not going to need any set or new here and we are not going to need deleted users like that and i will say user has been deleted and again async let's copy this for others otherwise i will forget again and again okay let's come here and write same middleware for others for the late user for getting a user we don't need any verification that because even if we are not logging we will be able to see any user but to subscribe any channel we have to be logged in or for on subscription like video and dislike a video let's see new request plate user i'm gonna choose delete method and localhost api users and our id let's change this again i'm gonna send you can delete only your account let's change back user has been deleted if i check here i'm gonna refresh as you can see it's not here anymore let's create others get a user i will say try catch block next and this error actually i'm gonna do the same thing for others like that okay now we are gonna get user it's really easy i will say cons to user await user model and find my id and i'm just gonna use request params and id after finding this user i'm just gonna send json and this user for subscription remember we are taking id here but it doesn't belong us it belongs other channel let's remember our user model here as you remember we have subscribers and subscribed users basically we are gonna add this channel id to our subscribed users array and we are gonna find this other channel and increase its subscribers number it sounds confusing but you are going to understand better basically i will say await user find by id and here i'm gonna use jwt id remember we have request user and we can use this id and i'm gonna add channel id to my subscribed users array to do that we are gonna use push method and i'll say subscribed users and inside this array i'm gonna add request params.id again this is our user this is other channels user id and also we are going to find this user and increase its subscribers number so i will say await user find by id and update this time is going to be request params and id we are in that channel right now and we are gonna increment its subscribers number to do that we are gonna use mongodb increment methods and subscribers and here one and that's all let's send our response to hundreds json and i will say subscription successful like this so i will do the same thing for a subscription i will come here and paste this time it's not going to be push it's going to be pulled we are gonna delete this user id from this subscribed users array and also we are gonna decrease these subscriber numbers so basically i will say minus one and let's see a subscription successful so we can like and dislike any video but before let's create a video otherwise we won't be able to test it so i'm gonna close them and open up videos first one will be create a video router post methods endpoint again is going to be verified token and controller name and it's going to be add video let's create export const add video request response next and again i forgot async and i'm gonna create others update late get a video plate cat okay it's enough for now let's add this add video let's create others it's gonna be a put method of course we are gonna need video id here and delayed method again and get and i'll say find id and i'm going to delete here that because you don't have to log in to find any video and that's all let's create i will say cons new video new video model and inside i will say request body but before i'm gonna add one more thing and it's gonna be our user id when we upload any video we are gonna add it here request user and id and other request buddy let's save this try catch next error again i'm gonna copy paste this i don't wanna waste time okay and inside i'm gonna save this video i'll say const saved video it's gonna be new video dot save of course i wait and i'm gonna send it successful and save video now we are gonna update it again we are gonna verify our id basically we are gonna find this video and we are gonna look inside this video and find user id and we are gonna compare this user id with our user id if it's equal we are gonna update if it's not we are gonna send an error i will say const video is gonna be await video find by id request params dot id and we can send here any error if you want you don't have to but let's say if there is no video return next of course we cannot use it like that i will say if and create error it's going to be 404 and video not found and right now i can compare user ids i will say if request user dot id equal video dot user id it means we are the owner we can update it const updated user await video find by id and update we are going to send here video id request params dot id or drag the video id there is a typo here and i will say set method request and body whatever we want to change and also of course i will say new true like that let me close this sidebar and finally we are gonna send our user response 200 and updated video oops why i said user is gonna be video okay let's think what we are gonna need more when we visit video page in our client site we are gonna increment video of views remember there is a view here and whenever we refresh the page we are gonna increase this so i will say put that because we are gonna update i will say view and video id here what else we can do we can get trend videos it's gonna be get method trend we can get random videos when we go to home page we are gonna see those random videos what else we can see subscribe channels videos let's create them here by the way i've ordered here writing as and i'm gonna return error for all three you can update only your video so i will do the same thing for delayed i'm gonna copy here we don't need here i will say find by id and delete and we don't need them i can clear you can delete only your video and i will say the video has been deleted and for this one i'm just gonna find the video and return i'll say const video video dot find by id it's gonna be request params and video id like that and i'm gonna return just video okay let's create others add view random trend and subscribed let's asap let's call them here i will add view trend random and subscribe videos okay let's create them it's really easy guys i'm gonna delete here video find by id and update request params and id increment use property just one the view has been increased that's all for random videos if you write here find is gonna sort those videos and bring to us but i don't wanna do this i just wanna get random videos to do that we are gonna use mongodb aggregate and i'm gonna write here sample so basically it's going to return us a random sample but we can write here its size and it's going to be 40 videos we are going to test them later let's say videos and videos okay and for trends we are gonna find videos but i'm gonna write here a sort method mongodb sort it's really useful i'm gonna write here my condition i'll say look at video views bring me the most viewed videos like that if you say one it's gonna bring the less viewed videos if you say minus one is gonna bring the most lift it's gonna be videos and here let's check again we are this user there is a subscribed users array and in this array there will be many ids we are gonna take all those ids and we are gonna find all videos of these user ids let's do that i'm gonna delete here and i will say const user firstly we are gonna find our user otherwise we cannot see that array i will say user find by id and request user dot id we can use this that because we are using verify token of course i didn't write let's write it here and after that i'm gonna find subscribe channels let's say const subscribed channels and it's gonna be user dot subscribe channels sorry users let's check again okay subscribed users and after that i'm gonna create a list and i'm gonna create a promise loop what i mean by that i'll say const list i will say promise dot all and i'm gonna find every videos of those channels that's why we are using promise here we are not finding one channel we are finding all those channels and i say subscribe channels and i'm going to use map channel id and it's going to return video dot find if user id equal to channel id of course inside curly brackets like that and after that i'm gonna return this list i will say response status json and i'm gonna return this list but there will be a problem here let's try actually firstly i'm gonna create some users sign up test test one oops test one gmail test2 okay it's enough right now i'm gonna create some video using this user i'm gonna sign in we have a cookie right now and i'm gonna create videos folder let's create new requests it's gonna be add video post method and i will say localhost it's gonna be videos and i'm gonna write here its properties let's say title the past video like my videos description test description and what else remember image url let's say test video url is gonna be the same and what else we have i forgot let's check title description in which video we can add tags but it can stay like that okay let's create okay as you can see it's here and i'm gonna sign in as second user and create one more video the best video from second user i will send and one more i'm gonna sign in as a test three oops we didn't create test test one test two i'm sorry test one and i'm gonna create the best video from uh let's say first user okay right now i want to subscribe a channel let's create here new request stop a channel it's gonna be put and again i'm gonna sign in as test i will send okay we are test right now and i want to subscribe to test one let's say localhost users and i'm gonna write here user id let's check okay we are test and i want to subscribe to this channel oops i forgot sub here i will send now okay i forgot here find pi id and update we are pushing and in the same way i'm gonna update here okay let's try again i will send subscription successful and also i want to subscribe to another user let's check test2 i'm gonna paste and send let's check our user i'm gonna sign in again to see here as you can see subscribed user user one and user two and if i sign in as a test one as you can see subscriber numbers one and again one perfect it works right now i want to fetch all videos of channels that i have subscribed let's create here one more request it's gonna be get subscribed videos or channels videos whatever localhost videos and it was up or what let's check again okay sup by the way there's a typo here i hope everything is okay let's check i'm gonna send and nothing is here it's 200 but something is wrong of course i forgot a weight i'm gonna send and as you can see videos are here from second user from first user perfect but the mistake is as you can see there is a nested array here to prevent this issue i'm going to use javascript flat method so i will say dot flat in this case let's try again as you can see it returns only one array and inside our videos perfect and also i can write here a sort method so we can see the newest videos first so i will say sort and i'm gonna write here javascript sort method b dot created add minus a dot created at if you don't know javascript sorting i highly recommend you to check on google it's not that complicated if i fetch again as you can see the latest video because we have created this later and other video perfect you can create other endpoints here like trends or random videos let's try actually get random videos random i will send of course it's gonna return all of them that because our size is 40. let's make this one i'm gonna send video from second user the best video again first user as you can see it's random how it works and what else we can do we can get videos by its text or its title that's right here by the way we are not going to need that we are just searching by its tags and title let's say search actually it's better naming let's create here i'm gonna copy this and i'll say get by tag and search let's use them here get by tag and search okay if you remember in our video model we have text array and it includes strings so basically we can create a query and take all those strings and we can write our condition we are gonna use express query let's say const tags and it's gonna be request query and let's say text and if i write here console.log and tags you are going to understand better right now i'm going to come here and say get by tag tags and localhost videos and tags and i want to write here a query how we are going to do this it's going to be question mark tags equals let's say javascript python c if i send this as you can see all those queries are here it's working like that it's really easy and it's a really common usage i'm sure you have seen this in many websites so we are gonna use it like that but as you can see they are not separated to separate them we are gonna use javascript split method i will say split and we are gonna split using those commas between them let's do this again i'm gonna send and right now as you can see they are separated so basically i can look inside these tags this array and i can search for those items let's delete here and i will say video find and inside i'm gonna write my condition we are gonna look inside text and i will say in methods basically it looks inside arrays and checks whether a specific element inside this array or not in this case we are using this text oops okay and i'm gonna write here a limit otherwise it's gonna return all videos for now it's not a problem but in the future when we add thousands of videos it's gonna be a problem so basically we are gonna fetch only to any of them let's try i'm gonna come here and change those videos we don't have any tags i'm gonna add here i will say javascript and one more let's say python i will update and second one let's say javascript and see i will update and finally third one i will say c and d let's try right now i'm gonna look for javascript and it's gonna return gels first and second one as you can see javascript javascript if i say python it's gonna return only this one let's say c okay perfect and also you can write here c and d and it's gonna return this one and this one and for other one search video i'm gonna use query again i will say const let's say query request query and let's say just q let's delete this and let's write limit and let's say 40 for example because it's going to be a search page so it can be more than 20. and i'm going to write here condition title will be the query which we write but as you can see this is our title even if i search for snt it should return this title so basically we are gonna use rejects here so i'm gonna say rejects it's really useful guys if you are using mongodb you are gonna use this all the time and i will say query and also i'm gonna write here an option and it's gonna be i basically uppercase or lowercase will be not important even if we write uppercase as t is going to find this video and let me check okay it looks nice let's check here one more request get by query localhost videos search and q will be let's say st i'm gonna send oops search can't use option ah it's gonna be options i'm sorry i will send again and as you can see st st actually all of them are best so it's gonna input that search for first and as you can see it's here it's that easy guys let's create quickly comments and after that we are gonna apply all those requests into our react application i'm gonna close everything here and open up commands i will say router post methods we are gonna create of course it's gonna be verified token we have to be logged in and it's gonna be add comment let's create them export const add comment async request response next and try catch next and error okay i'm gonna duplicate this it's gonna be delayed comment and get comments we are gonna get all comments of a video let's create them add comment plate comment and get comments it's gonna be get methods and delayed method of course we should indicate here any specific id and here video id of course i'm gonna delete this by the way i should import this import verify token from verify token okay let's create them it's really easy you already know how to do this i will say const new comment new comment and insight request dot body and also user id will be our id request user and id actually let's move this here and we are gonna try to save it i will say const saved comment wait command save and we are going to return this respawn status send saved comment not comment is gonna be new comment of course we created here and that's all i think that's too late to do that of course we are gonna identify our user to do that firstly i'm gonna find comment weight command find by id request parameters and id and also we are gonna find our video let's make this capital i'm gonna import them by the way don't forget that and i'm gonna write here the condition i'll say if request build user id equal comment and id sorry user id it means this command belong to us we can delete it or if we are the owner of the video we can still delete this comment we don't have to be owner i will say request user dot id equals video dot user id we are going to delete it i will say await command find by id and delete request params dot id let's send i will say status 200 and i'm gonna say the comment has been deleted and don't forget writing here as if we are not the opener of the comment or the video we are gonna return next create error 403 you can delete only your comment and what about this let's say cons comments we are going to fetch all comments i will say await command dot find we are gonna write condition and video id will be request params.video id remember here and finally we are gonna send it json and comments like that it's crashed let's try one more folder commands new request add new one post and i'm going to choose json and i'm going to add just description here and it's going to be first comment let's send of course we forgot video id let's choose one of them this one video id like that i'm gonna send okay perfect this is our user id this is our video id and description also let's create other ones second comment third comment and i'm gonna use this video id right now and try to fetch all those comments let's write here get all comments of a video i'm gonna paste it here and send as you can see all those comments are here perfect okay we finished our api right now we are gonna install our react application and we are gonna apply them there of course time to time we are gonna come back here and fix our some mistakes and also we are gonna add google authentication but for now it's the ending of api by the way i realized that i forgot writing like and dislike functionalities let's check okay as you can see they are empty let's create them if you remember in router we are passing in video id we can use it and inside video model as you can see we have likes and dislikes arrays so basically when i like any video i'm gonna put my user id here and if i already disliked this video i'm gonna pull my id out here from dislikes and for the dislike functionality i'm gonna do the same thing i'm gonna add here and pull out here let's do that i'm gonna open up user controller first here i'm gonna take my user id let's say const id request user and id let's take video id in the same way i will say video id and here i'm gonna update this video i will say await video dot find by id and update and i'm gonna pass here video id and i'm gonna push my id here but if i use push method even if i like this video before it's gonna push it anyway it means it's gonna duplicate my user id but i don't wanna do that so instead of push i'm gonna use add to set method it's a really useful method it just makes sure that your id is in the array only once even if you click the like button again it's not gonna add again and again so here i will say likes likes array and my user id and also if i dislike this video before i'm gonna pull out my user id there so i'm gonna use pull method dislikes and my id and that's all let's send a message response status 200 and json let's say the video has been liked so i'm gonna do the same thing for dislike i can copy here and paste but this time it's gonna be dislike and it's gonna be like let's try by the way i said user is going to be params of course and there is an error here let's check okay something wrong with try catch block that because i forgot this try here okay perfect let's check quickly i'm gonna come here and create like and dislikes users like and it's gonna be video id to do that we can just check random videos here okay we can take this one and paste it that sent the video has been liked i'm gonna choose one more video get random you can choose this one and i'm gonna make it dislike video has been like that because i forgot changing here video has been disliked of course okay let's check those videos i'm gonna copy this again and i'm gonna get this video new request localhost videos and remember what was that find and id i'm gonna send okay there is something wrong that because i forgot changing here it's gonna be get video right now i'm gonna send again and as you can see this is our video and in the dislikes array this is my user id i'm gonna do the same thing for other one let's check i'm gonna paste and send and this time as you can see this is my user id it's that easy by the way let's change this name get a video and what if i try to like this video again let's try i'm gonna come here i'm gonna change this name and i'm gonna paste here and it's gonna be like a game i'm gonna send it says video has been liked but if we check here as you can see it's not adding my id again it's here only once this is why we are using this functionality add to set okay it's ready i think if i forgot something we will come back here and fix them but for now we are gonna install a react app i'm gonna come here if you remember from last tutorial the design part of the application is here i'm gonna choose this one and i'm gonna import this project to my vs code to do that i'm gonna close here and create one more folder and it's gonna be client and inside this one let me open one more terminal here and i'm gonna go to client let me make this a little bit bigger and what i'm gonna do is to import this branch its branch name is react video ui i'm gonna come here and copy this link i will say git clone i'm gonna use only one branch so i will say single branch branch and branch name here remember react video ui and my link here and finally i will say dot let's see what's gonna happen as you can see it's cloning our react app here if i check all those files are here but as you realize we don't have our libraries to install them i'm going to use npm install or just yarn after that it's going to include all those libraries here okay it's ready let's start yeah and start and it's here perfect by the way youtube deleted our images here but it's not important we are gonna import our own so what we are gonna do we are gonna log in and register but before i want to show you how we are gonna fetch data using express api this is our home page i'm gonna shrink this and i'm gonna close everything here so firstly what i want to do is adding my api url here i'm gonna add it as a proxy so we won't have to write it again and again i will say proxy and remember our url localhost port number and api and right now we are going gonna use this proxy so we don't have to write this link again we are just gonna write our endpoints i'm gonna save and let's go to homepage pages homepage and as you can see there are many cards here right now we don't need them only thing we should do is to fetch our data remember we can fetch random videos firstly i'm gonna create use statehook here and i will say const videos set videos and when we fetch data we are gonna set our videos here i will say use state and at the beginning it's gonna be an empty array and i'm gonna create here use effect fact that because whenever i refresh this page i want to run a function and this function will be fetching videos function so i will say use effect this function whenever we refresh page and it's gonna run only once and i'm gonna create my function i will say const patch videos it's gonna be async oops and i'm going to need a library here to fetch our data we are going to be using axios let's open up one more terminal here and we can see better and i will say cd client axios i'm showing this okay it's ready let's say const response axios is gonna be get method remember and i'm gonna write here my endpoint it's gonna be videos and random and that's all by the way it's not coming let's import quickly import axios from axios okay of course don't forget here wait you can write here try catch block also if there's an error you can show it here but i don't want to show any error for now it's gonna make the video longer but if you want to you can create one more state here error set error and you can use here try catch block if there is an error you can set that error and show it here after this response i'm gonna set my videos response and data this data includes everything that api sent us basically all those random videos let's call this function here i'm creating a function here that because you cannot use async inside use effect like that as you can see it cannot be async that's why we are creating function and calling here okay by the way it's gonna be videos after that we are not gonna need any card here we are just gonna use one of them and i'm gonna cover this with my videos i will say videos and i'm gonna use map and for each video i'm gonna return a card like that let's see i'm gonna save and as you can see there are three videos it's that easy guys but here if you remember we have explore button and subscription button we are gonna fetch different data using those buttons so what i'm gonna do is to go to app.js by the way if you didn't watch the previous video it can be hard to understand because i'm not gonna explain every piece of components here if you didn't watch i highly recommend you to watch it first and it's gonna be much clearer okay if you remember we have a index root here i'm gonna create one more it's gonna be a home page again but i wanna give here a type prop and it's gonna be trend and i'm gonna copy this i'm gonna create one more it's gonna be subscription and for the normal index page it's gonna be random videos let's change them it's gonna be trends [Music] and it's gonna be subscriptions okay right now i can use those types here i'm gonna take as a probe and instead of random i'm gonna change this end point dynamically remember in our server i'm gonna open up videos we have random trend and sub we are gonna use those and points so we already passed here random trends up so we can use it directly of course to do that i'm gonna use backtick here and i can write javascript so i'm gonna just say type in this case is gonna be our dependency i'm gonna write it here and i will save let's see right now as you can see nothing has changed when i click here we are gonna go to trends page let's do that i'm going to open menu let's shrink this a little bit more if you remember we are using link like that react rather dom link so i'm gonna copy this and paste for explore and i'm gonna wrap this and it's gonna be trans page so i'm gonna do the same thing for subscriptions i'm gonna paste my link and it's gonna be subscriptions when we click on this button it's not gonna work that because we don't have any user yet but we are gonna test it later as you can see their colors are different to prevent this i'm gonna come here choose both of them and i'm gonna say color inherit so it's not gonna change the color okay perfect so i'm gonna click here we are in the trends page and our videos are here of course we cannot see which one is most viewed but after passing our video to those cards you are gonna see better let's do that i'm gonna go to home again and i'm gonna write here a key first don't forget if you are using map you have to give here a unique key not unique key we can use we have video and their id so we can use it and also i'm gonna pass my video as a prop so we can use it in the card component let's do that i'm gonna open card component and i'm gonna take this video right now we have video details so i can delete here it's gonna be video dot image url and video details that's right here video dot title and views here video dot views and created add date but if i directly use here video dot created at it's not gonna show us like one day ago one month ago to do that we are gonna need one more library and i will say yarn at timeago.js let's install okay it's ready let's import here timeago.js and i'm going to import format function you are going to see right now i'm going to cover createdate and we are going gonna transform into time ago.js let's see as you can see zero views 18 hours ago title and image of course we don't have any image yet it's just a broken link but we are gonna add this don't worry but there is a problem here that because we don't have any user information here channel information this name and this image to do that we are gonna fetch channel information here we are gonna do exactly the same thing i'm gonna copy here and paste this time it's not gonna be videos it's gonna be channel or user whatever you say channel set channel i'm gonna import use state and it's not gonna be an array let's say empty object i'm gonna import userfact channel and i'm gonna import axios okay and this time i'm gonna use user's endpoint that because it's a channel i will say find and i need to write here user id we already have video and inside this video we have user id we can use it video dot user id and after that we are gonna set our channel here response and data and finally i'm gonna call this function of course our dependency is video and user id whenever we change this user id it's gonna fire this function again and again let's use this channel also remember this is channel image i'm gonna change it channel dot image and here channel dot name and let's see right now as you can see test test1 test2 and we don't have any image yet perfect it works if i open up mongodb here and change those video views let's change this one it's gonna be a hundreds this one will be let's say 50 and this one will be let's say one let's check right now our trend videos i'm gonna click here and as you can see first one will be a hundred fifty and one but if you go to home page as you can see it's different right now if i refresh the page it's going to be changing that because we are fetching random videos let's refresh again as you can see it works like that i'm not clicking here because we don't have any user let's take care of this i'm gonna go to login page it was sign in page okay as you remember we have username password and email here let's create new states for them i will say const name set name use statehook and at the beginning it's going to be an empty string i'm going to do the same thing for others email and password but how we are going to change them we are going to use on change method so whenever i change this username input i'm going to set my namestate and it's going to be event target and value i can do the same thing for others it's gonna be password username again it's gonna be email and password okay we have our data right now we are able to make an authentication api request for this button we are going to make login request we have username and password we can send them to do that i'm going to write here onclick method and when we click on this button we are gonna fire handle login function let's create i will say const and the login is gonna be an async function that because we are gonna make a request and here i'm gonna send my credentials but before i'm gonna use here event prevent default so even if i click this button it's not going to refresh the page i'm clicking as you can see it's still here that's why we are using this function and after that try catch block and i'm gonna make a request i'll say const response weight axios it's gonna be a post method and my end and i'm gonna pass my credentials remember we are sending request and body we are doing exactly the same thing here we are sending name and password let's see if everything is okay or not i will say console.log response and data i'm gonna open up my console here and i will say test and my password i'm gonna sign in and as you can see it's successful and it returns user information here and we have subscribed to two users here okay perfect but how i'm gonna use this data everywhere it might be a problem that because we are gonna use it in navbar here in menu and when we open any video page in the comment section we are gonna see our data basically we are gonna need it everywhere to handle this problem we are gonna need a context api or redux of course you can use any other management tools also but in this tutorial we are gonna use react redux i know for some of you redux is terrifying but don't worry we are not using old-school redux we are gonna be using redux toolkit and you are gonna see how easy to use it let's come here open up sidebar and i'm gonna create one more folder here it's gonna be redux and inside this folder we are gonna create our redux slices what we are gonna need here we are gonna need user so i'm gonna say user slice let's create user slice.js and let's create redux toolkit i'm gonna open my documentation get started as you can see we are gonna need this library and also we are gonna need react redux let's say yarn add toolkit and react redux i'm gonna import them and let's see what we have here and i wouldn't say it's the best documentation ever but i will try to find out there's a quick start here here as you can see let's open up javascript firstly we are gonna create this function and after that we are gonna write here our initial state in our application the initial state will be user now we are not gonna have any user but when i click on this button we are gonna start fetching this data and if it's successful we are gonna update that user if it's not successful we are gonna show an error so basically we are gonna have initial state and inside we are gonna have user is fetching and error let's copy here you are gonna understand better right now initial state user will be null i will say is fetching or loading whatever you say at the beginning is gonna be false when i click that login button is gonna be true and if it's successful or if there's an error it's gonna be false again and finally error at the beginning is gonna be false if there is an error it's gonna be true and after that we are gonna create our user slice we are gonna name it it's gonna be user we are gonna pass here our initial state which we have created and after that we are gonna write our reducers basically it's gonna be functions that we want to use i'm gonna copy this and i'm gonna explain one by one let's paste it's gonna be user slice name will be user initial state and our reducers i'm gonna delete them but before let me explain that as you can see there is a increment function here let me show here actually there is an increment function and it takes our state at the beginning remember value is zero then we call this increment function what it does is to increment this value by one and it's changing this value and this function is doing the same thing minus one and also we can pass here any specific number let's say we are calling this function and we are passing inside 5 and it adds this payload to our state dot value in this case it's going to be 5 when we call this again is going to be 10 let's say we are calling this one it's going to be 9 and this one is going to be 10 again it works like that if you are not familiar don't worry you are gonna understand let's delete them and my first reducer will be login start i'm gonna take state i'm not gonna write here action like here that because we don't have any action that payload we are just gonna start our login process so i'm gonna say state dot loading and it's gonna be true it was false but we are starting fetching it's gonna be true i'm gonna duplicate this this one will be login success and this one will be login failure if it's successful it means we have a user so i'm gonna write here action and i'm gonna update my user i will say state dot user is going to be action dot payload as we did here in this case of course loading will be false because we are ending if there is an error loading will be false again that because we have a result and also error will be true so when we click here we are gonna fire this function if we have a user we are gonna fire this if there is an error we are gonna fire this function and let's say we have a logout function state and everything will be exactly the same here so we can use initial state return initial state user will be null again false and false or you can directly say state or if you want to you can say drag it like that of course don't forget state and equals it's exactly the same thing okay but now we are gonna use those functions i'm gonna come here and export them i will say export const login start success failure and logout and we are going to export them from user slice dot actions like that and also i have to export my user reducer basically this slice so i'm gonna say export default user slice dot reducer okay we have our functions we have our initial state but how we are gonna use them i'm gonna create here a store and let's check as you can see firstly we are gonna import configure store and our reducer and we are gonna create a store here why we are creating store that because we want to use this user object in every component so basically we are gonna have a storage and when we want to we will be able to reach this user so let's create this i'm going to copy like that and paste here of course it's going to be our user reducer let's delete here from user slice and it's going to be user user reducer so basically we are going to have a storage and under that we are going to have a user which is this user and inside this user we have our initial state user loading and error so when we want to use this user we are gonna go to store.user.user actually let's change this name if i make this current user for example it's gonna be much easier to understand let's change here and here okay in this case it's gonna be current user if you want to use this store user dot current user okay but how we are gonna use this store everywhere i'm gonna open up index here and i'm gonna wrap my application with redux provider and i'm gonna pass here my store let's do that i'm gonna say provider i'm gonna wrap my application and i'm gonna pass here my store store equals store like that and this provider comes from reac redux let's import like that okay right now i am able to use this store everywhere in any page and any component let's save here and let's start firing our actions start success and failure so i will say before starting before fetching data we are gonna use login start but to use that we are gonna need a dispatch function so i will say const dispatch and we are going to use use dispatch hook it comes from react redux let's dispatch our first action i will say dispatch and login start as you can see here we are not passing anything we don't have any payload and after that if fetching is successful i'm gonna write here login success and i'm gonna pass my user here remember how we are doing response and data it's that easy and if there's an error just right here login failure and that's all if you want to you can pass this error here and take this error as a payload action and update here but i'm using just true false it really doesn't matter right now and it works like that let's try i'm going to open my app if you don't have this extension you can find it for google chrome and firefox its name is redux dev tool if you search for it you can install this extension it's really useful so i'm gonna write here my name my password and i will say sign in and as you can see it fires login start first and after login success and it says current user is not null anymore it's this user and loading was true and it turned back to false you can see your action here this is our payload which we sent to logins access action function you can see your difference your state as you can see store user current user but we are gonna use this current user in our navbar and menu let's open up i'm gonna close everything here and open up never so we are gonna use react redux use selector hook so i will say const current user i'm gonna use use selector and i will say state this is our store remember state dot user there is a typo here current user okay let's import this use selector from react redux okay of course you don't have to write it like that i'm just test structuring if you want to you can say current user state user dot current user but it's easier way i'm gonna use it like that and right now i can use it here and i'm gonna write here a condition let's drop this link and i will say if there is a current user right here something if there is no current user show me this link let's say here user for now and as you can see it's here we can show of user image username and also i'm gonna add here a button that we can upload a video so i'm gonna delete here and firstly i'm gonna create here a user container of course we don't have yet but we are gonna create and after that i'm gonna create this video button and we are gonna have avatar which is user image and finally our username so i can directly write here current user dot name let's create those components here i will say const user styled component and it's going to be a div and i will make this display flex they are going to be horizontal and i'm going to say line item center i'm going to give gap between them and font width will be a little bit thicker and finally remember we are using dark mode and light mode so we are going to change its font color depending on our team is going to be team.text they all came from previous lesson and i'm going to create here const water again style dot image 32 pixels height will be the same i'm going to say border radius 50 so it's going to be a circle and let's give any background color here so if there is no image we are going to show this background color like that let's see okay perfect as you can see our button user image we don't have any image and our name so i can do the same thing here if there is a user i'm gonna delete this section let's copy this use selector and i'm going to open menu let's come here and import this selector and use this current user this login and also i'm gonna delete this hr of course they're in the same level we cannot use them like that we have to have any parent here so i'm gonna cover them like that okay so i'm gonna write here my condition if there is a current user actually if there is no current user let's check as you can see it's not here anymore perfect it's that easy guys what slice we need more we are gonna need video slice that because when we click on any video here let me stop this we are gonna see video page and we are gonna have many functionalities like like the video dislike the video subscribe to the channel or if that video belongs to us we will be able to delete it so basically we are gonna need video slides also let's create actually i'm just gonna duplicate this and change the name video slice and let's see video slice name will be video and i'm gonna change here we are gonna take care of this later but i want to show you how we can combine them i'm gonna go to store and here i'm just gonna say video equals video reducer of course i should import this like that but also there is a problem here that because as you can see our page has been refreshed and we don't have user anymore let's click again test sign in as you can see it's successful but if i refresh the page it's not here anymore let me make this page bigger a little bit okay so what we need here basically we need to persist our user to do that let's search for persist use with redux persist it's a little bit complicated i know but this is what we exactly need let's import this library yeah add redux persist and i'm gonna copy here and paste here and we are gonna need this persist config like that and as you can see we are going to need persisted reducer but it says root reducer but we don't have any root we are using our reducer separately what we can do we can combine them i'm gonna come here and say combine reducers so i'm gonna create here a root reducer i'm gonna say const root reducer combine reducers i'm gonna send my user reducer of course inside an object and video reducer it's exactly the same thing what we did here user user reducer video video reducer but we are gonna combine them it means we don't need here anymore we can use root reducer but we are gonna per system as you can see we are passing our route reducer here let's do that and instead of root reducer i'm gonna pass here persisted reducer and finally we have to use this middleware otherwise it's gonna give an error to prevent that error i'm gonna write this also like that don't worry about that it's nothing important for null and finally we are going to export this persistor of course i will say export and at the final we are going to create purchase gate and it's going to cover our app like we did here with provider and we are gonna pass this persister let's copy this open up index file not this one client and i'm gonna wrap my app let's import them and persistor let's try right now i hope everything is okay i'm gonna come here and i'm gonna write test my password i'm gonna sign in okay we have a user right now i'm gonna refresh the page as you can see it's still there and if you open redux dev tool you are gonna see that our reducer is persisted right now it basically stores our user and other elements inside the local storage this is how we are reaching even if we refresh the page and also since we logged in we have a cookie here and it includes our access token it means right now we are able to upload any video comment to any video or fetch subscribe videos right now i'm gonna click and as you can see there is no error anymore and this is all videos of the channels which we have subscribed remember we are test and we have subscribed to test1 and test2 and they have only one videos it works properly and by the way i forgot showing how to login using google button i wanna delete this user for now and after that we are going to go to sign in page of course we can create logout button somewhere here i don't know let's go to sign in page again and here i'm gonna add a google button to do that i'm gonna go to firebase.google.com and let's get started i'm gonna create a project let's say video i will confirm and continue we are not gonna need any analytics i'm gonna create project it's gonna take a while okay it's ready and here i'm gonna choose build and authentication and in this page i'm gonna choose google provider and i will enable here you are gonna choose your email address and save okay it's ready we can use it right now but to do that we are gonna need to install google firebase i'm gonna add it here yarn add firebase and after that we are gonna initialize our firebase application let's come here i'm gonna choose web app again let's say video app as you can see npm installed firebase we have already done this and after that we are gonna initialize let's copy this and i'm gonna create one more file here and it's gonna be firebase dot js i'm gonna paste it let's delete those those comments of course i recommend you to put this api key in an emv file but for now it can stay right now we are gonna use google authentication to do that i'm gonna import one more thing here import from firebase and auth and i'm gonna distract your get auth function and i'm gonna create authentication here i will say export const auth and get auth function like that and also i'm gonna export this app let's say export default that because we are gonna use it when we upload any image or video of course we are gonna do this later but okay it can stay and we are gonna need one more thing here and it's gonna be google auth provider this is the provider that allows us to log in using google button so let's say export const provider and it's gonna be new google provider like that okay we can use them in our sign in page i'm gonna open sign in and i'm going to import it here auth and provider right now we can create a button and when we click on that button the google sign-in page will show up here as a pop-up let's import that i will say import from firebase authentication again and it's gonna be sign in with popup okay we can use it let's create our button here i'm going to add one more ore and between them i'm going to create my button sign in with google let's create here onclick method click and when we click on this button it's gonna fire sign in with google okay let's create this function somewhere here i will say const sign in with google okay let's use our popup sign in with popup and i'm gonna add here my auth which we have created in the firebase file and provider let's see how we are using it as you can see we have already done them and here after this process it returns us a result and this result includes our user information let's try i'll say 10 and console.log this result and if there's an error we are gonna catch it it can stay for now and let's see what's gonna happen i'm gonna save i will come back here and open up my console i'm gonna click here as you can see it opens this page when i click on my account as you can see there is a result here and inside there is a user and this user includes all those information my name email my image and others we are gonna use three of them display name email and photo url okay i have my information right now i can add those information into my mongodb let's create here of course it's going to be async and i'm going to say axios post my endpoint google we are not using sign in that because we are not using any password and i'm gonna pass here my information of course inside firstly we are gonna send our name is gonna be result user.displayname i'm gonna duplicate this we are gonna send our email and we are gonna send image email and what was the name photo url and after that if everything is okay we are gonna again dispatch login success function so i will say then it's going to return us a response it's going to be our mongodb user so we are going to say dispatch login success and payload will be response and data of course at the beginning we can create login start and here if there is an error it's gonna be login failure okay let's go to our authentication route and as you can see there's a google endpoint but we don't have any function yet let's create i'm gonna come here export const google auth i will say async function request response next and we are gonna try catch and let's see what we are going to have firstly if we already created a google account we shouldn't create new mongodb account basically we are just going to find this user and we are gonna do exactly the same thing here we are gonna create token and we are gonna send this token as a cookie and we will send our information of course in this case we will not have any password so we can directly use user and document let's do that let's try to find out our user i will say const user user model find one and i'm going to find my email address because it's a unique address request body and email after that i'll say if there is a user it means we have already registered before so we are gonna send our cookie and information so let's copy this token we are gonna create new one and we are gonna send our response like that in this case it's not gonna be others it's gonna be user dot document it's exactly the same thing but what if we don't have user it means we are going to register for the first time in this case we are going to create a new user i will say as cons new user is going to be new user and we are going to pass here all our body and also i'm gonna add here one more property and it's gonna be from google if we check our user model as you can see we don't have yet let's create here and it's to be easier to understand whether it comes from google or not so i will say from google type will be boolean and by default it's going to be false okay let's come back and after that i'm going to save this user const saved user is going to be await new user and save and finally i'm going to do exactly the same thing i will create a token and send my user in this case it's not gonna be user it's gonna be saved user it's that easy guys if you didn't understand here i recommend you to watch this part again it's gonna be much easier there is nothing complex here and finally of course next error and that's all i hope i didn't make any mistake i'm gonna go to authentication route and call my function google auth ok let's try i'm going to open redux again and sign in with google as you can see login is success but our current user is not here let's check okay it's empty okay i forgot here saved user and i forgot here wait and inside user as you can see password is required i'm gonna delete this it's not gonna be required let's try again and right now it's working perfect current user test lama my email and user image perfect but this image is not here let's correct this navbar as you can see we don't have any image here i will say source it's going to be current user dot image okay perfect it works so even if i try to sign in again it's not going to create new one it's going to return to existing user let's see as you can see it has test 1 test 2 and la maldive perfect of course here we already have a user we are not supposed to see this page and also you can create somewhere here logout button or you can create here a menu and a logout button and when you click on that button you can fire this logout action i believe that you can do this and what else we are gonna have let's close everything and open up video page here and we are gonna create a lot of functionality here firstly i'm gonna take the current user remember how we are doing this using use selector hook and also we are gonna use this patch to apply our actions firstly what i want to do is to fetch a single video when i click this button if you remember we are going to test page but this time we are going to change it let's go to cart page and i'm going to change this link it's not going to be test anymore it's going to be our video id of course i'm going to use backtick quickly and i will say video dot id like that of course inside call the brackets like this okay let's try again i'm gonna go back and i'm clicking this and we are going to this page as you can see this is our video id and we are gonna take this id and fetch our video to do that we are going to be using use location hook i will say const path and i will say use location it comes from real gradle dom and let's see what we have console.log path of course there is an error that because in our recommendations section here we have a lot of cuts but we don't have video id what i want to do is to remove them for now and here okay as you can see this is our location and we have here path name and it includes video and our id so if i separate them this video section and id section and if i take the second part of this string we are going to reach this id so i will come back and i will say path name and i'm gonna use split slash and i'm gonna take the second item basically i'm gonna create two use states here i will say const video set video it's gonna be use state it's gonna be an empty object one more and it will be channeled let's create our use effect and i will say const fetch data async function try catch block and inside i'm gonna fetch two data first one will be video i will say const video response rate axios it's gonna be get videos and i'm gonna write here my video id that's right here backticks and video id and it's gonna be our path and one more it's gonna be channel response and i will write here users find and we have video here and inside this video remember we have user id and after that i'm gonna set my states i will say set video video response dot data and one more channel response and here is gonna be channel like that and in this case our dependency will be path as you can see i'm gonna paste it here like that and i'm gonna use this fetch data here okay but i'm not gonna use directly this video if i do that i will not able to like dislike or subscribe to the channel of course i will but it will not show up here immediately i have to come here and refresh this page each time when i make any action to prevent this instead of use state i'm gonna create a video slice we have already created here i'm gonna come here and create current video and i'm gonna store my video here instead of use date so basically i'm gonna delete this and this and let's create current video and i'm gonna change here let's say fetch start success and failure and i'm gonna delete this logout let's change them also fetch like that in this case we are gonna need one more use selector here and it's gonna be current video state state and video okay right now after fetching data i'm gonna update my video slice let's write it here actually i will say dispatch fetch success and i'm gonna pass here video response and data in this case we have one more dependency and it's dispatch okay right now we can use this current video i'm gonna copy this it's gonna be title current video.title views created at date so i'm gonna use format again like that current video and create it add date what else there is a like here i'm gonna say current video likes remember it's an array so i can take its length and i'm gonna put here a question mark that because at the beginning it's not gonna load probably dislikes and other things will be channel let's change them channel.image channel name subscriber number channel.subscribers and description but remember this is our video description not channel description so i'm gonna say current video and description let's see okay they are here perfect but we don't have user let's check again okay that because i forgot here writing data okay perfect we don't have any avatar so let's take care of those likes and subscription button i'm gonna write my condition there for this like button i'm gonna check whether my user id inside these likes array or not i'm gonna do the same thing for dislike let's say current video dot likes if includes my user id which is current user dot id it means i already like this video i'm gonna write here some other icon if i didn't like before it's gonna be this icon let's put this icon here quickly okay and i'm gonna do the same thing here i will say if current video the dislikes includes my user id it's gonna be this icon if i didn't dislike before it's gonna be this icon okay let's write like and dislike functionality and you are gonna see better i'm gonna come here and say on click methods and handle click or handle like let's do the same thing for dislike handle dislike okay let's create them const and the like async await axios it's gonna be a put method and i will say users like and video id current video dot id let's do the same thing for other one dislike and dislike let's see i'm gonna click here of course we cannot see here that because we didn't handle this with redux but if i refresh this page okay the problem is here it's updating our user not video i made a mistake let's choose this video from second user i'm gonna like and refresh as you can see it's here but i cannot see this immediately here to prevent this i'm gonna create an action let's come here and say like we are gonna take state and action and i'm gonna create a condition here firstly i'm gonna check whether i already like this video or not if i didn't i'm gonna add my id inside this likes array and if i disliked this video before when i click this i'm gonna delete my user id from here let's do that you are gonna understand better right now i will say if state and current video and likes includes my user id in this case i'm gonna send this as a payload so i will say action dot payload it means i didn't like before so i can add my user id which is action and payload so i will say state dot current video dot likes and push action payload i'm adding my user id inside this array by the way if you are not using redux toolkit you cannot use push method you cannot mutate your state but thanks to redux toolkit we can do this easily like that and if i dislike this video before i'm gonna remove my user id from dislikes state current video dislikes and i'm gonna use splice method and i'm gonna find my user ids index to do that again state current video and dislikes i will say find index and i'm gonna find my user id user id equals action.payload after finding my user id i'm gonna delete it like that if you don't know splice method you can just google it for five minutes you are gonna understand here better and i know it looks a little bit complex but actually it's not if you didn't understand just watch it again i just add my user id into likes and i removed my user id from dislikes so i can do the same thing for dislike i will say dislike in this case i'm gonna make likes dislike dislikes like that let's export them and try i will say like and dislike okay i'm gonna come here and i will say dispatch like and i'm gonna send my user id current user dot id let's copy this and paste here and it's gonna be disliked like that let's try i'm gonna refresh the page i'm gonna dislike as you can see it's not here anymore if i like it's here awesome it works and if i refresh the page as you can see it's still here but because we have added this into our mongodb it's that easy guys so i can do the same thing for this subscribe button firstly i'm gonna write my condition into video page as we did for like and dislike i'm gonna come here and i will say if current user dot subscribed users includes this channel id it means i subscribe to this channel in this case i'm gonna write here subscribed if i didn't i'm gonna write here subscribe let's see as you can see i've already subscribed this channel if you remember i'm the test and i've subscribed to test2 and test1 that's why we are seeing this but i'm gonna implement this to redux also so we can see it here immediately so i'm gonna open user slice and i'm gonna write here subscription i'm gonna take state action i'll say if state.currentuser.subscribedusers includes dot action.payload which is channel id i'm gonna delete channel id from here subscribe users dot splice method i'm gonna find the index find index and channel id equals action action.payload and i'm gonna delay it if i didn't subscribe before and when i click this button i'm gonna add this channel id inside subscribed users i'm gonna do the opposite so i can come here and say else if i didn't subscribe before i will say subscribed users push action dot payload let's export this like that i'm gonna come here and right here on click method it's gonna be handle subscribe or sub let's create const handle sub async function firstly i will say users subscribe and channel id and after that i'm gonna dispatch my action and it's gonna be subscription here and as a payload i'm gonna send channel id with underscore but i want to check this endpoint did we create for unsubscription also or not i'm not sure users okay there is unsub 2. so we should consider this too so it means i'm going to write one more condition here actually it's going to be exactly the same current user subscribe users i'm gonna take here and paste if it includes channel dot id i'm gonna call unsub api request if i didn't subscribe before it's gonna be sub and after that we are gonna change it here let's see as you can see unsubscribed i'm gonna refresh it's still here that because in the mongodb we are not subscribed i'm clicking again and subscribed perfect it works so let's change this video we were using youtube video but i'm gonna delete this i'm gonna create here video frame and its source will be current video dot video url let's create this using style components i'm gonna say const video frame it's gonna be styled dot video i will say maximum height 720 pixels it will be a hundred percent and i'm going to say object fit and cover if we check here we are not gonna see anything that because we don't have any video url but it works so what about those comments let's open up comments quickly i'm gonna do exactly the same thing i'm not gonna waste any time and paste here i'm just gonna explain i just created comments use state here at the beginning it's an empty array and i created use effect and we are fetching all commands of a video using video id of course we didn't send any video id here let's send quickly comments video id it's gonna be current video dot id we can use it here video id and right now i can use it as you can see there are many comments here we are gonna use only one of them map command i'm gonna wrap this and i'm gonna delete others and i can push this comment here of course we need a key don't forget this key let's say command dot id it's a unique key okay right now i can take this command by the way this is gonna be our current user image let's do that i'll say current user dot image of course we are gonna need use selector and we are gonna fetch current user like that okay as you can see we don't have any comment yet i'm gonna open up command component and i'm gonna take my comment here it's gonna be comment dot description let's check other videos maybe we added somewhere here not this one maybe this one okay as you can see first comment second comment and third comment perfect and also we can change this name and image quickly you already know what we are gonna do we are gonna fight user we are gonna do exactly the same thing here i will say channel or user whatever you say and we are going to fetch our user like this let's create use effect quickly channel response or just response of course it should be inside a function const fetch command async like that i'm gonna import axios and it's gonna be comment and user id in this case it's gonna be our dependency i'm gonna pass it here and i'm gonna call my function like that and after that finally i'm gonna set my channel it's gonna be response and data let's use it channel.name and its image like that as you can see all those comments belong to us and we don't have any avatar okay perfect so far so good and only thing we should do is to create new video when i click on this button we are gonna show here a pop-up and we will be able to upload image video its title its description whatever else to do that i'm gonna open nailbar quickly and we are gonna use this video button i will say on click when we click this we are going to open the pop-up to do that i'm going to create here a use state i will say const open set open it's going to be your state hook at the beginning is going to be closed i will say false and when we click on this button it's going to be true set open is going to be true okay right now we have this boolean according to this open variable we can show our popup let's create here upload.jsx i'm gonna create my function and i'm gonna use it here let's use under container actually that because we are gonna use position absolute so i don't want to destroy any component here i'm going to say if it's open show me upload component and i'm going to send set open here that because inside upload component we will be able to close this set open and let's take it here firstly i'm gonna create here a container and inside we are gonna use a wrapper that because our container will be full screen and this dropper will be something like this a small box and inside i'm gonna create a close component here and we will be able to close this pop-up let's say x is gonna be our closing button i will say title upload a new video and i'm gonna create the rest but before let's take care of them i'll say const container styled components it's going to be ideal wrapper clause and title close tight and it's going to be h1 attack let's make this full screen i'm going to say with 100 percent height 100 percent and position will be absolute i will say top 0 left 0 so it's gonna start from here and contain all this screen and i'm going to give a background color let's say black when i click this button as you can see it's totally black but i want to give some opacity here something like that okay perfect we can see the background but not that much visible so let's enter our wrapper here i'm going to say display flex align item center and just y content center what about this dropper i will say 600 height will be the same my background color will be our theme color bg lighter and text color will be themed.text so it's going to be white on the black theme and black on the white team i'm going to give some padding it's going to be display flex but i'm going to make it vertical so i'm going to use flex direction and it's going gonna be a column let's give some gap between them and i'm gonna make it position relative that's because we are gonna use close button this button and it's gonna be position absolute and i'm gonna move it somewhere here of course i've zoomed in the normal view of our website is something like that but i'm just gonna zoom in for viewers who watch this in laptops or mobile phones okay anyway so i'm gonna come here and say position absolute i'm gonna give top and right is going to be 10 and cursor will be pointer and when we click on this button we are going to close this pop-up let's do that as you remember we have set open here i'm gonna say on click i'm just gonna close this pop-up like that let's try i'm gonna click as you can see it's not here anymore i'm gonna click here perfect and i'm gonna align this title text align center okay awesome and i'm gonna add here some inputs let's say const input styled input i'm going to give some border and color using my team and border radius will be 3 pixels heading will be 10 pixels and background color will be transparent otherwise it's going to be white we don't want to do this of course we didn't add let's add here input something like that our first input will be typefile and it's going to represent our video file when we click this we will be able to choose any video so i can say accept only videos so i can write it like that in this case we will not be able to upload any other file it's gonna be only videos let's create one more input here it's gonna be text and i'm gonna give placeholder and let's say title i'm gonna create one more input but it's gonna be a little bit bigger so instead of input let's say text area and it's gonna be for our description text area is going to be exactly the same let's use it description and placeholder will be description and i'm gonna give row here let's say eight lines so it's gonna be a little bit bigger okay perfect and one more input here and it's going to be our video text let's say separate tags with comma and finally one more file and it's going to be for our thumbnail images so in this case it's gonna be image like that and finally a button here const button it's gonna be exactly the same button that we created before you are gonna see right now so i'm not gonna create from scratch i'm gonna come here and say upload like that let's give some small labels here before those files i'm going to say label image and label video let's create quickly i'm gonna duplicate this label is gonna be label and i'm just gonna decrease font size it's gonna be 14 pixels like that okay it looks much better and clearer right now we are gonna upload videos using firebase i'm gonna go to console again and here i'm gonna choose storage i will say get started we are going to use it in the test mode so we will be able to write and read i'm going to choose any location here and done it's going to be ready during this process let's create our use states what we are going to have i will say const image set image is going to be used hook at the beginning let's say undefined or null or whatever you want i'm gonna do the same thing for video so whenever i add here any video i'm gonna set my video here let's do that i'm gonna say on change when i change file here i'm gonna update set video and it's gonna be even target let me close this sidebar target files but we are gonna upload only one file so i'm gonna choose first one and i will do the same thing for image [Music] set image oops like that what else we are going to need we can show uploading process somewhere here like ten percent fifty percent a hundred percent and when it's done we can right here upload it successfully to do that we are gonna need two more use dates and i'm gonna say image percentage and video percentage like that and at the beginning they are gonna be zero when we start uploading we are gonna increase them and what else we are gonna have our inputs here like title and description i will say title description and one more it's gonna be text empty string empty string and empty array okay we are gonna update them let's come here for title i'm gonna say on change method set title it's gonna be event target and value and same thing for description i can do the same thing for these tags but i don't want to do this directly that because we are going to separate our items to do that we can use split method so let's say on change and handle text let's create const handle tags and i'm gonna set text event target value but i'm gonna split them using comma of course we are gonna need event here okay we have all of them only thing we should do is to upload our image and video so whenever i add here any video it's gonna directly start uploading and for image it will be the same so basically we are gonna need to use effects i will say use effect and the dependency will be video and other one is gonna be image whenever we change video it means whenever we add any file here it's gonna fire this function and it's gonna be the same for image so basically i can create here upload a file function let's say upload file and we can take a file and we can call it inside our user i'm gonna send to video and here i'm gonna send to image okay but what we are gonna write inside this function basically we are gonna use firebase uploading process okay there's a full example here as you can see we are gonna need some functions here let's import them like that and inside firstly we are gonna call our storage like this and we are gonna create a storage reference let's copy this and paste here but as you can see it provides here a folder name we don't need that we are just gonna need here file name but if we do that whenever we upload a file with same name i don't wanna make any conflict to prevent this i'm gonna create my own file name let's say const file name to do that we can use new date we are gonna create name using this date get time plus file dot name so it's gonna give us a unique file name so i can use it here and models as you can see upload task and here the process is beginning let's copy here and if there is an error i'm gonna leave it like that of course we don't have default here that's right as you can see there is a progress here and it shows us how many percent we have uploaded so in this case we are able to set this image percentage and video a percentage to do that of course we are gonna need one more prop here and it's gonna be let's say file type or actually we can say url type that because inside our api video as you remember we have video url and image url we can drag the update time here in this case i'm gonna make something different i'm gonna actually delete this description and title and i'm gonna make them inputs set inputs and at the beginning it's gonna be empty object basically is gonna include everything related to our video like title description video url in which url so we don't have to set our states like that we can directly call here a function let's say handle change i will do the same thing for description and i'm gonna give here a name and it's gonna be let's say title and it's going to be description let's create this function and you are going to understand better i'm going to come here before this text actually const handle change and i'm gonna set my inputs i'm gonna take the previous inputs and i'm gonna return the new one whenever we change our description or title we are gonna update inputs i will say take the previous items and add here one more item and it's gonna be event target name and its value will be event target dot value basically when i try to change its description it's gonna take the previous items title and description but it's gonna change description to its new value why i did this that because i want to add my image and video url here basically we can add them into these inputs quickly and it's to be much easier when we try to create new video using mongodb let's select this data and instead of console.log i'm going to set my percentages so i can write here a condition i will say url type if it's image url it means we are gonna update image percentage it's gonna be this progress if it's not it means we are gonna set video percentage like that okay let's check here what else we are not gonna handle these errors and finally it's gonna give us as you can see this url and we are gonna add it into mongodb let's copy this and paste here if it's successful again i'm gonna do the same thing let's come here and copy this and paste here and in this case it's not gonna be target name it's gonna be our url type and this link download url let's use those percentages here for this file i'm gonna write here a condition i'm gonna say if video percentage is bigger than zero show me something if it's not it means we don't have file and show me this input component so what i'm gonna write here let's say uploading video percentage that so i can do the same thing for other one for image like that and image percentage okay let's try by the way there is a mistake here that because we are trying to upload video but we don't have any file yet so i'm gonna write here if there is a video called this function and in the same way if there's an image called this upload file function i'm going to open this pop-up let's choose a file here as you can see i cannot choose this video i'm going to choose this one but it's not uploading there is something wrong that because we have to pass here our application so i will say app and if you remember in firebase we are passing this app by default so let's import i'm just gonna say app from firebase and that's all i think by the way it's gonna be like that and also we didn't pass here our urls video url and image url let's try again i'm going to open up our pop-up choose an image okay it's not here again and this time i forgot here image percentage let's choose oh as you can see it's a hundred percent that's right here percent also okay perfect right now let's check our storage i'm gonna refresh as you can see we have the same image but different names there are two images that because i refreshed the page and it uploaded again and it works perfectly what about this as you can see this time i can choose only videos let's choose as you can see percentage is moving like that but it's not flat let's round this percentage so i'm gonna use math rounds and progress let's see again as you can see this time perfect and after uploading image and video finally we are able to send it to our db let's create here handle upload const handle upload it's going to be async function again i'm going to say prevent default i don't want to refresh the page and let's use it in our button i will say on click method and handle upload right now we have everything we need so basically i'm gonna say const response await axios and post method videos and i'm gonna pass my input and my tags and after that if it's successful we are gonna close our popup set open is gonna be false and i'm gonna say if response and status equal to 100 of course you can use try catch also but i want to show you something different here and i want to be navigated to home page i'm sorry video page so to do that we are gonna use use navigation hook let's create here const navigate it's gonna be use navigate hook from react router dom and using this navigate we will be able to go to our video page i will say video page and new video id which is response data and id of course it's videos not video so i'm gonna do exactly the same process i'm gonna upload and we are in this page as you can see this is our video and this is our title and description awesome guys it works perfectly but here as you can see we don't have any controls i cannot start this video or make some configuration i'm gonna open video page and where is our frame here i'm gonna say controls in this case we are able to start this perfect it works i can make this full screen also so what else we need we need recommendation sections here if you remember we just comment them out i'm gonna open them by the way i can create new component instead of this i don't wanna make everything in this video component so i'm gonna come here and say recommendation my function and remember here as you can see it's flex2 i'm just gonna delete this and paste it here and of course it's gonna be container and i'm gonna use it here so how i'm gonna fetch related videos here basically i'm gonna take text and according to those tags i'm gonna fetch videos i'm just gonna drag the paste here you already know what we are doing i just created videos use effect and when we run this recommendation component we are going to fetch some videos and if you remember we have text endpoint and we can send our text by using express query after that we can use those videos video and i'm gonna call here card component and don't forget key video dot id and video will be video so how we are gonna send those texts here in this video page we already have the video and we already know which tags this video is using so it's really easy to send only thing i should do is to come here by the way i'm gonna import recommendation component here like that and i'm gonna send text and it's gonna be current video dot tags it's that easy and also remember we are using type here and it's gonna be small okay let's choose this one by the way it looks pretty nice i'm gonna choose this one and as you can see related videos are here okay perfect and the last thing we need is searching videos when we write here any query and click on this button by the way why it's black i'm gonna open navbar and i'm gonna move it here into parent okay perfect when i click on this button we are going to open search page and we are going to see all those videos i will say new page search dot jsx quickly container it's gonna be start components dot d and it's gonna be display flex so i will say flex wrap it's gonna be wrap and i'm gonna give some gap between them so let's create const videos set videos it's gonna be use statehook at the beginning is gonna be an empty array and quickly i'm gonna create here use effect we are gonna fetch our videos i will say const fetch videos it's gonna be async function and response equals weight and we are gonna make our api request to do that again axios and get methods and remember which end point we have here we have search and in this controller video controller as you can see we are selecting a query and according to that query we are sending maximum 40 videos so i will say videos endpoint search and i'm gonna write here a query how we are gonna do this let's go back to number and i'm gonna create here one more use state and it's gonna be our input what we are writing here basically let's say query just queue set q at the beginning is going to be an empty string and whenever we change our input we are going to update this i will come here and say on change and it's gonna be set query it's gonna be event target and value and when i click on this button this search button we are gonna be navigated to search page so i will say on click and to use navigate we have to use here use navigate hook i will say cons navigate is to be use navigate from reaccloud.on in this case we can use it right now here and we are going to go to search page and also we can send our query here so i will say q equals of course i will use backtick again and just queue whatever inside our input okay right now we are able to use this endpoint it's exactly the same endpoint here in our videos search question mark queue and any title here so we are gonna use directly this search string so i will come here to do that we are gonna use again use location hook i will say const query use location hook and search it's going to give directly this string so we can use it here i'm gonna say just query and after that we are gonna set our video state i will say set videos it's gonna be response and data let's call this function and here as you can see we have a dependency and it's going to be query so let's use it here it's going to be a container and inside videos map and for each video we are gonna call our card component i'm gonna give unit key here video dot unique id and i'm gonna send video let's see i'm gonna write here javascript for example i will search oh okay i forgot creating search page in the application of course i will come here and one more path and it's gonna be search i will see search and i'm gonna delete here i will write here javascript actually we are searching just titles not tags i'm sorry so i will say awesome i'm gonna search and as you can see it's here let's choose other one the common name as you can see best best and here i'm gonna write here past and it's gonna search and fetch all those videos perfect okay guys that's all i think please consider that it's just a tutorial i'm not providing you any complete application if there is any mistake any error just calm down and use our discord or facebook groups we are gonna fix them of course there are many features are missing like logout button or any complex error handling but try to find out the solution it's going to be really good challenge for you to improve your skills if you can't find anything just right in our groups there are many people there helping each other i highly recommend okay that's all i hope you liked it if you learned something new today please like the video you can support lama there by joining to channel or using the link in the description below and you can help me to create new videos just like this and i hope i will see you in the next tutorial goodbye
Info
Channel: Lama Dev
Views: 158,445
Rating: undefined out of 5
Keywords: Video sharing app, video app tutorial, video streaming app, video website, full stack video app, mern stack video app, youtube clone, html css, react, react tutorial, react course, react for beginners, mern stack tutorial, react node.js, react node.js tutorial, react node.js mongoDB, react node.js firebase, react video uploading, lama dev
Id: CCF-xV3RSSs
Channel Id: undefined
Length: 207min 29sec (12449 seconds)
Published: Wed Jul 13 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.