React File Upload Tutorial with Drag-n-Drop and ProgressBar

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello youtube today we are going to create a multiple file upload using formic if you look into my screen i will drop a few files into our drop zone and immediately they are uploaded into cloudinary they are not going to eat our server at all they are going directly to cloudinary so all these json that you see on the screen this is on our own browser nothing yet hit our server then when you click submit yes we will send this json to our server so our server just has to store the urls not the images itself i will explain later in the video why that is important okay right now let's just see what happens when we have errors in our files because they are let's say too big for example this video over here is 65 megabytes my limit in this form is 300 kilobytes so at this stage you can't click on the submit button because we have an error if you delete that one then once again you can submit your form now i also added in this video a background color of dark because a lot of people have been asking me for that so you have this code in the video repository you can go there and check but for now let's jump into vs code when you clone my repository this is the code you are going to get as you can see i already have some boilerplate in order to use formic when we go to the browser this is what we are going to get now we need to make ourselves a question when we want to remove that hello youtube and put in its place a drop zone in order for us to draw our files into do we want to do everything manually and then handle all the events by ourselves or do we want to use the library like react drop zone well for today's video i'm going to use react drop zone because it's a library i really love to solve this exact problem so if you look into this documentation and i will zoom this for you you can see that the way you use this library is basically just by this use drop zone hook so this use drop zone hook will return two very important functions in my opinion the first one is the get root props and that get root props you will pass into your main container in this case that div that you see over there the next function is the get input props which as the name implies we will pass into our input field if you are asking yourself what properties are we passing to the div those are all the properties and event handlers that we are passing into that div similarly to that one what we do over here is the following list so these are the two lists that we are sending both to our div and our input field now you may be asking okay bruno but what happens when i drop a file what's going to happen well then this function that we have over here will be called and as you can see over here now we only have the accepted files but we can also have the rejected files that failed our validation let's say you want only files up to one megabyte and someone tries to send a file that is two megabytes even before we do the upload to the server this library over here will send in a second parameter of this function called the rejected files okay and another thing that you need to keep in mind is this function will be called only with the last files that the user dropped so for example you drop five files right now then you go to your file system and you drop two more the second time this function is called is called with only two files not the seven files in total so you will have to keep in a use state in your component those other files and every time this function on drop is called we will merge those into the existing files okay so with all that said let's start to copy this function over here even though we don't need this is drag active i will remove that in a little bit let me just go to the source and i will create a folder called upload so you can copy this folder into your project and you will have all the files that i will create today and the first file i will call it a multiple file upload field dot tsx dx export function multiple file upload field and then i will just paste that code as i said i will remove this e-drag active i will remove this bit and this bit okay now we just need to import the use drop zone and we need to import the use callback let me try again and now we imported those two as i said the first thing we need to do is to now create a state that i will call files the set files use state which is an empty array for now and then i will have the accepted files and the rejected files right those two are arrays as well the first one the type of these is an array of files the second one we can over over here and see that there is a file rejection array so you might already be thinking that we will have to normalize one of those two right because well they are in different types so if you now go inside this file rejection right let me just click you can see that the file rejection is a file so up to this moment we are good and then we have errors so what we can do is pick up the accepted files and transform the accepted files that are an array of files into an array of wrapped files or file rejections if you want to i don't like the name file rejections because it's already implied that something failed so i will just create a new interface over here interface and i will call it for example uploadable file it's probably a bad name still but better than uh file rejections i guess feel free to change that name from uploadable file to something else okay now i will just say that it will be an uploadable file array okay i will import this use state because it's not imported yet and so the only thing we need to do now is to transform our normal files into an object with file and errors with an empty array so let's just do mapped accepted equals to accept that files dot map we will receive a file and now we will just return an object with file and errors with an empty array now what we need to do is just to go to our set files right set files we will just do the current files that are already there saved so we will do current we will do the mapped as acc which is the accepted and then whatever name i call to these ones rejected files right so basically when we do this and i have the wrong typing so now it's good i can format this code and we are already handling the dropping and we are already saving all the files rejected and not rejected into the same array so then in the future when we start to show stuff we will show an accepted file accepted one rejected one accepted one accepted one rejected for example if you keep two lists because you can do this in that way as well instead of having all the files into the same list you can have a list for accepted files at least four rejected files but then if you if you save those two lists in separate then you will have a list of all the accepted files and the list of all rejected files in this case i want to keep a list with the order that we submitted the files not if they are rejected or accepted and the order depending on that okay but both solutions are valid it's just two different ux perspectives none is wrong or right okay so now what we need to do is just to say that we have those files so let me just come over here and i will just do the following json.stringify just for our own debug okay to make sure that we are on the right page let me just come over here into our index.txx replace our beautiful hello youtube by this new component right and hopefully now vs code will help us import that file and it did thank you very much vs code we go over here into our application we refresh and now you can see that we have that empty array i can click over here putting this board in these cats i will do open i have two files i can also put one more file over here which is very good and now i can even come and drag a file over here so when i drop a file over there it's also working so this initial part is now kinda done what do we need to do after this well after this we can now come over here delete our debugging from there because we don't need the debugging anymore we know it's now working i will just create the react fragment i will put this react fragment at the bottom and over here the only thing i will do is that i will look through all my files okay and for now i will kind of ignore that we can also have rejected files okay so what i'm going to do is over here i will loop through all the files we have so i will do files dot map file and in reality this is a file wrapper because we have that wrapper in the file of the file is inside that thing and then we also have the errors so we will have a file wrapper and now we need to create a new component and we can call it what let me think single file upload with progress probably a bad name but let's go single file upload with progress.tsx let me just copy these let me just do export function of these and let me just return the div with the single file upload okay so now we have this file so we can come over here and the only thing i'm going to do is to pass a file and we will do file wrapper dot the real file okay so basically now we can import this file so typescript is not complaining at us it will complain because we don't have that file yet so let's come over here create an interface okay export interface props and we will do file with the real file not our wrapper anymore we can copy this and do file and over here we will have that single file upload with progress so if we go now over here we should have no warnings anymore um and we should be good in a bit when typescript stops complaining about it because we have a file so it should be good right so now what what do we want to do uh with these well we want to do the following every time that this component is initialized because we have a new file to start the upload right we want to have a use effect that will do the upload for us so let's start by creating that use effect right and we will just say that this use effect will be only initialized once right and inside this use effect now there is something that i need to tell you about if you are deploying to for example versailles or netlify which i know many of you are you have those two things that you should read probably pause the video and read but basically what it means is the file system in both versailles and netlify that is a temporary file system or as some people call it an ephemeral file system okay what it means is you can use it as a temporary file system but nobody guarantees that in 10 minutes the files will be there that is something that they are inheriting from aws lambda that's the platform they use okay so aws lambda has the same problem if you tell me but bruno i'm using something like heroku for example so i can save into my file system well you can but heroku as well has the same problem is an ephemeral file system so nobody guarantees that in a week your file will be there so in those scenarios we will use uh any cloud provider that provides for example aws s3 basically you have azure cloud storage which we call the blob storage uh you can have google cloud storage you can have cloudinary the one we are going to use today you can have imagex for example and you might be asking okay with all those options will the code differ no the code is exactly the same you basically point to a different url and you may change uh the key where you put the key right cloudinary will put the key into the form data itself i will show you that in two or three minutes and azure for example puts in the other but those things are basically the same the way you use them okay so with that being said now we need to talk about another problem which is if you are using for example just fetch okay and you will do method post and then your url etc fetch doesn't allow us to have the progress okay you can upload with fetch no problem whatsoever but you can't have the progress if you are uploading a file with 20 megabytes you can't understand the progress of your file yet if you are using something like axios axios already has the progress so you can do url and then you put your form data and then you can have over here i think is a function called on progress that will give you the progress of what's happening and axios only has that because behind the scenes access is using xml http requests and by the way for me it's very hard to say xml http request so if i fail during the video i'm already saying sorry in advance okay because it's really hard to say that for me but now what we need to do is to use that xmlhttprequest and basically better that one will have the progress but you will see that's very tedious to use that so let me just create a function over here that we will call upload and i will just call upload over here because then i will just do const url equals to await upload file and this is the one where we are going to use our xmlhttprequest so let's start by creating that function so we will create that function we will call it with a file and now we will just do the following return new promise and inside this one we will have the resolved and the rejected right and this is now where the fun starts right this is where the phone starts so let me just put the url depending on the service you are using this url will be different right and now inside here we will do the following const xhr equals to new xml http um oops xml not html bruno xml http request right and now we need to handle the success the error and the progress itself right the first thing that we usually do is to open okay and open will say the method that we are going to do and the url the url we will go in a minute to the cloudinary website to copy the url right then you also need to have uh the on success which over here is called load okay so we will do onload and the unload will be just a function oops just a function and i will show you how cloudinary handles that but this is where we are going to pass the url where cloudinary saved the file okay we will come back into this line in a minutes time probably then we will handle the on error and the on error it will return an event so we can just do reject with that event all right and now this is oops this is just an equal and now this is where we are going to do the progress so we will do xhr.upload.onprogress right and this function will return an event to us event right and basically what are we going to do uh with this event we are grabbing this event and we will do the following we have event dot total okay which is the total size of our file and we will have how much we already loaded so for example let's say we loaded 500 kilobytes our file is one megabyte which will be the total we can just do the load divided by the total multiply by 100 and we then round it and we have the percentage so let's start by doing that just keep in mind one very small detail that can be important for you there is something here that is the length computable if this length computable is too false you can't trust the total value i will leave somewhere a link to the mdn or a print screen to the mdn explaining that bit okay just do that validation over there if it is false don't trust the total amount so as i said let's say percentage equals to we will do the loaded divided by the total right by the total and we need to put event dot good job bruno we will need to put event data as well over here multiplied by 100 now the only thing we need to do is to call a function over here that we can say on progress we will just create a percentage which will be a number and it will be returning void so let's just do the following on progress on progress math.round of percentage so we don't send anything like 33.222222 okay we just sent 33 or 34. not anything in the middle all right and then the last thing we need to do over here is just to go over here and do xhr dot send and when we do descend we will send a form data okay so how can we create the form data we will just do the following form data equals to new form data right and form data dot append and we will do file this is usually a common convention okay we will do file and the file will be the file itself so let me just scroll this at the bot at the top which is easier to read now the only thing we need to do is that in cloudinary they will as i said before have the key they don't call it key they call it something else we will check and they will have the key over there okay so that's the only bit that's missing and when we go now to the cloudinary website you will see that our thing will start to upload so let me just go to the documentation in cloudinary and we will use that demo account as i said so the url is over here this is the first thing i want to copy is the url and the second thing will be the key itself so let me just copy the url i can say const key equals to whatever key they are having which is basically our upload preset that's what they call it and i forgot the d so i just need to do box reset and now they have i think is upload preset so let me just go at the bottom and call this upload preset let's just create a new upload for you to see what cloudinary is returning to us right so if we do this upload this is what cloudinary uploaded uh sent to us in the response we can go to jsonlint for example and one of the properties that they are going to return to us is the secure url as you can see here so if i just copy this secure url you can see this image is what we uploaded right now okay this is the image we uploaded and probably you are already aware of this image i already showed it on the video a few minutes ago now this is what we uploaded so we can just come over to the secure url because we will use that on the on load right this function over there so let's just do response equals to xhr dot response text okay and basically at the time json was not that known yet or not that used yet i think xml http request is coming from the ie nine or eight times so a long time ago right so at the time they don't have anything like a response json so that's the reason i'm using the response text i'm parsing the response text and then just using the secure url okay so now when i start to use this i can go over here i will have a progress function right so let's just pass a function which will be our progress and we can even put it in a in a state over here so let's say progress set progress equals to use state we will start that state with zero so in reality we can even pass this bit over there right and our component will just set um we'll just set that no problem whatsoever right now what is it complaining about file is not assigned ah because we have a file array and it should be a file only okay basically i will just import these and now we have most of the things that we know that we need sorry in order to upload so let me just go over here i have this url so i will just do a console log for now of the url so we can test it ourselves and then we can start to pass the url up the chain okay and i will just do the following progress over here so we can see the progress because these images are very very small let me just see if we are now no errors because now we don't have a file right that's why we were having the errors before so i can come over here and as you saw these values were increasing and i have quite a few things over there but let's start this from fresh now if i come over here and i upload for example this file okay i will upload it over there you will see that we now have a url over here this key is normal because we you are not passing the key in react right if you want to solve that error we just need to come over here do this index oops index and we just need to do this key equals to e d x okay now react will not complain anymore right i can just refresh this page pass it again and now react will not complain and we have our upload there so if i open this in a new tab you will see that i have another image that you already saw on this video right so that bit of the upload for us is now working which is very good news let me just delete all of these things that we have open we don't need them anymore right i can now go over here and we are handling already the uploads for the for the the ones that passed validation this is very good now you probably want and i want as well to have some progress bar over here instead of having what we have at the moment because it's a bit sad what we have we don't have anything special so before we do anything with the url let's take care of the progress bar so let's go to the material ui documentation okay and in the material ui documentation for the progress bars you have quite a few examples you can have circular ones you can have uh basically these custom ones i honestly just like the normal ones i don't need anything special over here so i will just copy the super normal one go back into our code and i will just do the following i will put this inside the react um sorry a grid item because we are using material ui and the grid item will basically put just spacing between them because in the top level let me show you the top level oops in the index i have this formic width with a container right and i'm saying spacing of two so each item will have a spacing of two between them that's the only reason i'm wrapping everything now in a grid item okay and then i just need to paste what we got so this is the linear progress we got it will be of type determinate so it's very good that's exactly uh what we need and now the progress actually is the same name that we are already using so i don't even need to change anything over there i can go back over here to our locals 3000 and if i drop three or four files let me just drop all these files so it will take a bit longer to upload especially my video so i will not put the video it will just take a bit too long and you can see we already have some progress bars so the next thing that you might want to do is to have the title over here at the top and for that i will create a file called file editor is probably a good name right and so let's create a file editor because then we will use the exact same thing for the files that we reject okay we are not handling the file rejections yet so let's just do file editor over here dot dx and let's do export interface file adder props for now we are not going to do anything with that one and then we will do file editor and what are we going to receive one of the things that we can receive in the file either is the name of the file so we can do file name or in reality we can even receive the file itself and then in the future if we want to also put the file type or something we already have the real file so let's receive the real file so let's do file and let's receive the real file and then what else do we need to do we probably want to have a delete button at the right um sorry at the the right side of our progress bar right it makes sense to have a delete button there so let's do that let's receive an on delete and basically when we delete what we are going to do is to send the file to delete okay so this is avoid function this looks very good for me and we will have file header props this is just what we need grid we will have a container okay because now we want it to be in this direction in the horizontal direction we have did that container sorry uh and the next thing we want to do is to have a grid item with the file dot name i guess it's file.name and i didn't import grid yet let's import the grid thank you vs code uh and then the other grid item will be our button so we will do a button which will be a material ui button and i think we can have a size for the button yes we can and i will put the smallest size we can have which is a small button let's call this button a delete and basically on click on click we will just do on delete of the file itself this seems good to me right let's let's give this one a try even before the we have the the on delete let's just give it a try let's have a file editor we will pass a file which the file will be the file we already have and beyond delete we will just create a function and actually for now we do absolutely nothing right so let's just put this we will import the file editor this seems good to me right now let's just go back over here and we already have the file name and the button to delete now the only thing we want to do is to put them with space around okay let's go over here i don't even uh it's here i don't even remember the name for that but i think it's space around okay we need to go to the material ui documentation i don't really remember what's the name i think is spaced around uh i think he's with the display property but i need to check i don't remember so let's see if they have a space around justify okay let's do that just t5 equals to space around and basically that's enough we can also do an align items to just center them because if you saw them right now i will probably get an error when i try to do that let me just try to upload something if you see they are not vertically aligned with each other so i will just do and align items to the center in that case they will be vertically aligned as well right let's go over here and they are at least aligned with each other and let's just put space between not space around so this way they will go to the extremes and this is starting to look actually quite nice right this is starting to look very nice the only thing i need to change is if you see these are not aligned with the drug so i need to put the drug also in a grid item from material so let's just go into our thing over here let's just say that it's inside a grid item so now it will be aligned with everything we have okay we save we go back to our file and my computer kinda crashed oh okay is it alive okay okay my computer is back to life so basically we already have this thing and now they are aligned with each other which is a very good starting point right let me go over here once again and as you can see now the next thing you probably want to do is when we click to delete the file you want to delete the file right so let's come over here into our single single file upload and we will create a non-delete and this will be a function exactly the same as the other one we have there so will be avoid so we will receive that on delete over here and we will just pass that on delete over there now we need to go into our multiple file upload and we will do the following on delete and we will just do on delete function so let's create that function over here into our component function on delete we will receive a file and now the only thing we need to do in this function right is to loop through the elements right check which of those elements is basically um that file right and basically return that one so we can use a filter for that let's say set files oops set files we will get the current list of all the files right and let me just do this way i have all the files right now so the only thing i need to do is to go into those current files okay new files equals to current dot filter right and now i will receive the file wrapper so i will just call it fw which is the file wrapper and i will do file wrapper dot file equals equals equals to the current file right and now i just removed oops it's the opposite is different from the file and basically i have a list without that i just need to return this list return this list and now we are good to go if you don't want to have the return or the color verses we can just do the following and now you are good to go as well i just need to remove this semicolon and now we are good to go we removed um all the files that are not the one we have we can come over here let me just upload two or three more files for us to test them so i can click those they are going to upload i want to delete these cats i click and that gets is gone so the first thing i think we are in a good stage right now to also then start to um update our url right because if you saw we know about the url right now over here but we are not doing anything with the url so let me just format this code the next thing is on uh url change or on uploaded i think is the weather name when uploaded right or on upload on upload is a better name we will just do the following we will send the file so we can then do something very similar to the delete but this time instead of we just use a filter what we are going to do is do a map and then use this url to add an url to the file and the errors that we already have so let me just do that url string this will be just a void okay so we just need to come over here and do the following on upload i will just do the file and basically i will send the new url which is that one over there i just need to now receive that function and this should be good to go why is it complaining ah because in our promise okay over here i didn't set the type of the promise right yes i didn't so let's just set the type of the promise and now this will be a string and now this one should stop complaining we are in a good place right now right let's go back into our uh component over here and we will pass a function on upload and we will create a function called on upload as well and we will do something very similar to what we did for the on delete on upload we will receive a file we will receive a url which will be a string right and we can even copy paste this one right and we will do something very very similar the difference is that this time we will do a map and now let me just delete all of these oops uh yeah all of this from here right because now in our map the only thing we need to do is to check the following if the file wrapper dot file equals equals equals to our current file we need to return the file as is right oops the file wrapper as is plus a url which will be our url and then in this one we just return the file wrapper that's pretty much what we need to do the only thing we need now to also do is our uploadable file doesn't have any um url over there so let's just add a url which can which is optional because at the beginning the url is not set only when we finish the upload of the file we will set that url so that bit seems good i can format this code come to the bottom seems a bit unreadable but good enough i trust prettier on that let me just refresh this page let me just upload a few files can be those files once again they look good and if i go to the bottom i don't have any values yet because i'm not connecting with the formic yet but i can just come over here and we can just drop a json.stringify of the files right so we can do our own debug before we connect with formic now let's just come over here and we have all the urls as you can see url let's just test one of those urls to make sure that everything is working as we expect i need an http at the beginning and if everything is working as expected it is let me just copy another one to make sure that it's working because that's exactly the same one we saw before and it's working right so basically now what we need to do is to connect this with for me that's the next step so how can we do that well if you look into our index dot dx over here in the initial values we are not passing any initial value so let's start another field over here called files and over here we will pass name equals to files right so we will need to now update our multiple file to receive a name which will be just a name string and this is starting to look good so let's just go into our name of the string and we will just do the following cost we will receive three properties over here it's an array with three positions in a use field okay and we will just pass the name and now the first position we actually don't care that much about that first position because it's the value of the field itself so we can just open over here and we can see what we are going to receive right um field helper so the first one is the field input props i really don't care about the meta as well but i care about the helpers so if you don't care about the first parameter or the second we can pass just underscores and now we care about the helpers because the helpers is where we have the function to do helpers.set value okay and so how can we set the value well actually we are in a very good place every time that these files change we just want to set oops to set the value in those helpers and we will be doing the connection with formic so let's just do a use effect and basically this use effect will change every time our files change okay and the only thing we need to do is helpers.set value is oops files that's just it we just override whatever value is there with this new value and we are good to go if you really need these four validations you might want to also do helpers.set touched to be true for what we are going to do today this is not important but for some scenarios this might be important so let's just say that when he changed we put it to true and you are good to go right as i said for today i don't care i will leave it commented if you need in your application okay so we can go to our browser we can now refresh our browser right click to submit a few files for example the cat and that one we do that and you will see that now after our um file ended the upload formic already has the url over there so this is going in a good place the next thing i want to do is to do when our files failed validations okay for example if you have a validation of 300 kilobytes and our file failed that validation well i don't want to even submit the file okay let's go that one and over here if you saw i'm just doing everything to this to the the single file upload but as we discussed 20 minutes ago probably this video is already with 45 minutes almost so as we discussed probably like already 20 minutes ago this this bit will be um for the errors and for the good files right so what can we do we can change this a slight bit so instead of being like that let's just keep that one over there and i will start to change this one and then we can delete the previous one okay so we can just come over here and do the following if the file wrapper dot errors dot length oops length i never know how to type length this means that we have an error okay so we can just do div error bad luck right we just have an error over there now if for some reason we don't have the error so else we will have uh this thing as is no changes whatsoever to that thing right instead of having if else usually i don't like to have if else is in um in my jsx in the middle of it so let's just do a normal function over here and let's do a ternary so let's say if we have them we will do these otherwise so oops otherwise we will have that okay and this way we just need now to come over here and do agreed item and i will just do a grid item over here at the bottom and this seems very good to me right what do you think is it good for you i think this is good for what we want right let me just now come here and we can just also remove this bit we don't need that bit anymore and i can come to the use drop zone and let's say that from now on we only accept for example um videos right so let's say we accept video only we don't accept images or anything else we say we accept every single video format let me just format this code so it's easier to read and now hopefully when we upload an image we should see error so we can then create our own error error handler okay now let me come over here let's refresh this page oops refresh this page and now when i try to upload for example this image we should now see error over there so this is working as we want if i come over here and i upload this video which is 65 megabytes it's starting to upload and that bit is good okay let's come over here and create another file that we can call it for example upload error upload or validation error whatever you want to call it i will call it upload error even though this is not an upload that file this is even before the upload was made but in the middle of the video i can think of a better name so i will go with upload error right and i will just export interface upload error props and we will see what we are going to receive which is probably just the file itself in order for us to pass it to our uh file editor okay so let's just do function upload error which will receive whatever properties of type upload our props right and so what are we going to do over here inside the first thing we want to to have in this one will be um a red line right so instead of having a primary progress bar we want to have an error progress bar that will be the first thing then the second thing we need to have is the other so let's start by a react fragment right and now we will have a file editor file editor okay and the file ladder receives a name and i'm now sorry a file so we will pass the file and then it receives a non-delete which we will pass an undelete function right so let's type this so we will say file on delete will be a file of type file and we will do just void we will receive those so we will have file and on delete this starts to seem good let's just import the missing uh import so we need to import this one from file other and this one is already there now let's go to the material ui just to see how we can customize to make some style into our progress bar and i guess they have some examples over here of them changing the progress bar aspect for example this one should be good enough for what we need and actually yes this is basically what we need we can copy this bit call it the error linear progress bar so let's put it over here we can delete most of it because we just care about the background color itself i don't care about anything else to be honest i can just come over here i need to import these and vs code is about to crash poor vs code i feel sorry for uvs code oh god vs code come on okay let's start by importing this one then we can import the create style and i don't even need to have that team over there because typescript is smart enough to know about them so what we need to do now is to do the fully team dot palette dot error dot main and that's the color i care about i want to change this to be an error linear progress bar so we can come over here and say that we can copy from this one actually right we can come over here copy the variant and the value so let's copy the variant and the value we will say it's already 100 percent right this seems good um and we have usually what we need from there which is a good starting point now let's go back over here to our localhost 3000 and if i refresh and pass something over here i should see the error component because we are not even calling it anywhere yet so let's just call it over here right let's come over here and do an upload error we will pass the file which will be the file the on delete will be the same on delete so i think we are good to go right this seems very good we can come oops we need to import the file okay and now it should be good to go right so we need to do a file wrapper dot file and now when we have that we can go back over here we can select one file that is the expected one i will put all files so they will file and i want them to file so they failed which is good let me just test the delete so it also works so we already have quite a lot of things uh done what is the next thing we might want to do as i was saying at the beginning we can now do some more validations over here if you want to but to be fair i think you you will see most of the validations you can say for example max size right and by this mac size you will be able to understand all the failures that you will have let's say we want to have 300 kilobytes times 1024 and this is around 300 kilobytes okay and we can also pass the error into our component over here so we can do error equals to oops error equals to file wrapper dot errors right and this is all the errors that our component will have so we can come over here right now and just copy those errors which is a file error array okay so into our uh what is our upload error it's over here and i will just do the following over here i will import this file very nice oops very nice and i will just do the following errors and at the bottom of my um of my upload itself i can just put a list of the errors that happened so let me do this let me go errors dot map and now i have the single error that happened to me and the only thing i need to do is for example to have a span where i will just put all the errors one after the other and the error have something called the message so error dot i think his message isn't it error error dot message that's exactly that i will just stop for like five minutes because my computer is driving me crazy i think my computer is a little bit better right now so let's try it again let's go over here and let's upload for example this file and as you can see this file is bigger than the 300 kilobytes that we selected so we are going to show the message at the same time if i select for example all the images i know that some of my images are bigger than 300 kilobytes so i will have multiple error messages for example over here i have saying that the file is larger than 300 kilobytes and saying that the file must be of type video so i can come over here instead of having a span i will have a div so we will have the the messages one after the other and basically this will be what we need if you want you can put the messages in red using the typography in a material ui okay so for example typography i will just put this at the end typography and i will say that this typography will be with the color uh error okay color equals to error so if i save this and we go back over here you will see that now the messages have the same color right if for some reason you don't like these messages right i can show you something over here message and i can also show you error dot code so there is a code and if you want to translate the code yourself or do something with the code because you don't like those default messages you can see that the code for this one is file invalid type and for this one is file to large so you can grab those codes and create your own messages if you want to right okay let me just delete this bit over here and now i think we have everything that we need for this video i will just remove now the accepted and then we will do a bit of validation for the upload button okay when we click to upload the not upload to submit the form now i think we have everything we need over here so we have our upload error with everything that we might need we have our single file upload with everything that we might need we have the upload we have the delete we show the progress of the files so everything seems to be very nice over there we have this which is connecting ourselves with the formic component it's handling everything that we want to handle right now i can say that we will accept for example only image so any image and we will accept video right so this is the types that we accept if you try to submit the pdf for example we don't accept you can also put stuff over here by the file extension you can say dot pdf for example okay so if i just make that way and i remove those two then i only accept pdfs okay so you can even use the file extension if you don't want to accept all the image formats you can say for example i only accept jpeg images so all my images that are of the format png they will now fail okay i can come over here and as you can see i only have those two images so i can upload those two this one actually is bigger than 300 kilobytes this one is not and all my other images that are not one of these formats that that are over there i will just upload one which is png and so it will file because it says the file type must be jpeg video or a dot pdf which is not our case right now so we have that validation bit done the last bit we want to do is actually in this initial file let me just close all the other files so my visual studio code doesn't consume as many resources in my machine and now we just need to put a validation schema over here before we do that let me just do the typical values console.log values values if you watch my videos with formic probably you know exactly this line by now so resolved set timeout of two seconds for example and we will do the resolve with two seconds i think is oh promise bruno learn how to type promise so basically we have now a fake loader a fake timeout when we submit our form and the last bit we really want to do is a grid item with our button which will be of type submit and we can call this button submit for example right i will just import this button from there this button is now imported and so what we want to do we want to not be able to submit so that our form is invalid every time that we don't have a url right of all our um uploads if you see over here some of them they will not have a url so when we don't have a url it means that bad luck we can't submit we have or an upload still in progress which is one option or we have an error either scenario i don't want people to submit the form okay so let's come over here and the only thing we need to do right now is the following we will do validation schema oops valid validation schema equals to and now let's just import up over here so let's import array object from you we will also need the string for the url itself okay so let's just do a string and now the only thing we need to do is the following object the the string that we care about oops the string that we care about will be url and so we need to say string dot um minimum value or in this case we just need to say required right and we have that string over there now because this is an array i just need to do the following and i will have an array over here oops my computer is actually very very very slow i'm so sorry and so the reason this is failing is because we don't have an object over here with files and then i need to now close that object over here and now everything should start to work right i can now format my code and as you can see we have the files which are the initial files otherwise formic will have no way to know what are we trying to validate right and now yes now if we go over here and i just refresh our page and i put something that will file and i am sure that something will file i can select all of these files right and submit them you will see that we have quite a lot of failures over here and so those failures they should now be in our formic errors and because we have errors even if i delete this just for you to see i will not be able to submit so i can click but we are not submitting when we delete the files that failed for example this file file this file failed this file also filed this file filed this file failed almost everything failed except our cats so if i now click submit now yes now we have a submission successful right and we have everything that we wanted to do in this video i guess if you need any other question because it's already like one hour long and i might be forgetting one use case or another use case so always uh feel free to go to the comments and ask me but i think we have everything we proposed at the beginning of the video so if you like this video please like the video subscribe to the channel if you are not already and i hope to see you in the next video bye
Info
Channel: Bruno Antunes
Views: 20,360
Rating: undefined out of 5
Keywords: file upload drag-n-drop, file upload formik, upload files react.js, upload files with formik, file upload progress bar, react multiple file upload, react file upload form, formik file upload, react-dropzone, file upload dropzone, formik file upload tutorial, drag and drop file upload, next.js file upload, next js file upload, upload with progress bar, react upload drag-n-drop, cloudinary next js, cloudinary react, cloudinary file upload react, react file upload tutorial
Id: MAw0lQKqjRA
Channel Id: undefined
Length: 59min 5sec (3545 seconds)
Published: Tue Feb 23 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.