React File Uploader With Express (Using React Hooks)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] this video is sponsored by dev Mountain if you're interested in learning web development iOS or UX design dev Mountain is a 12-week design and development boot camp intended to get you a full-time position in the industry to learn more visit dev mountain comm or click the link in the description below hey what's going on guys so I've had a lot of requests to do a tutorial on file uploads with react and the reason I haven't touched on that yet is because there's just so many options for a back-end as far as where are these images going and how are they going to get stored and so on so what we're gonna do is something very simple we're gonna use Express along with a package called Express file upload which I just found and it's really really easy to use you also have options like mult or with Express which I do I do have a video on but multo is a little more complicated I want to focus more on react in this video because it doesn't really matter as far as the backend you could be using Express you could be using PHP you could be using cloud storage like firebase or AWS or cloud Andheri as far as the backend it's it doesn't really matter we're just gonna have an endpoint that we hit that we send the files to what we're going to spend most of our time is the front-end is the user interface here and I've used bootstrap for the UI elements but you can see we have a progress bar we're gonna have an alert component so it's actually pretty nice if we select a file ok the file name will be right here and then when we submit we're gonna use Axios where we can actually grab the file upload progress and we're gonna implement it into this progress bar so I'll go ahead and submit and you'll see that it fills up to a hundred percent we get our file uploaded alert and the way that I'm creating is this progress bar will go back down after 10 seconds so that it doesn't stay at 100% and then the image shows here with the image name or the file name alright so and if I go ahead and open this in a new tab you'll see that we're gonna have it go to the uploads folder within within the react public folder but of course you could direct it direct the image or file wherever you want so that's what we're gonna be building guys we're gonna start from scratch with the back end and we're gonna be using react hooks a sink await all the latest practices so this it will be a little while you know I wanted to create something nice rather than just say here's an upload a file upload button and that's how you upload a file I wanted to implement you know the progress bar and just create a nice little uploader alright so let's go ahead and get started we'll jump into vs code and we're gonna start with the back end so down here I'm going to just run NPM in it - Y which will create our package Jason and we're gonna install our dependencies for the the back end so I'm gonna clear this up and do NPM install Express and Express - file upload so those are our regular dependencies and then we're gonna have a couple dev dependencies so let's also do NPM install - upper case D node Mon and also concurrently which is going to allow us to run the backend Express server and the react server at the same time and we just have to add a couple scripts here as well so let's go right here and just scripts and we'll change this to start so this is just gonna run node and then our main file which I'm gonna call server dot J s so might as well change this alright and then we're also gonna have a node Mon server J s and this is going to be called server alright and then we'll also have our clients so this will be client and this is to run the react dev server which is going to be NPM start however it has to be in the react folder which we're going to call clients so we're going to add - - prefix client which will go into the client folder and then run and p.m. start okay and then lastly we need our dev script which will run both using concurrently so concurrently and we're gonna want NPM run server but we have to put it in scaped quotes so we're gonna do that and then NPM run server same thing with the client so NPM run client and then one last double quote all right so that will run both so let's save this close it up and let's create our server dot J s so this is actually going to be pretty simple we're gonna bring in Express and set that to cry or Express and let's also bring an Express - file upload and we're gonna call this file upload okay now we need to initialize Express and we need to initialize file upload so we need to do app dot use oops and then just pass in file upload with some parentheses okay now let's do app dot listen on port 5000 put in a callback here and just do a console log and we'll say server started okay now we just need one endpoint for our upload okay so this is the endpoint we want to send a request to from react and send along our file so it's gonna be a post request so app dot post and it's gonna be slash upload of course you could use whatever you'd like and then let's pass in our function here and first thing we want to do is check for this request dot files because that's what it's gonna come in as we want to see if that's null okay we want to check to see if that's null if it is then gonna return a response we're gonna send a status of 400 which is a bad request and send along some JSON which will just be a message telling them that no file was uploaded all right now if there is that request dot files then we want to pull our file from it so I'm going to create a variable and I'm gonna set it to request dot files dot file okay and this will will define whatever this is in react I'm going to call it file and then all we need to do is take that file object in it now it has a method of mV which is to move it so this just takes in a path to where we want to put that file so I'm gonna put in some back ticks because I want to use the double underscore dur name which is the current directory slash and then go into the client which is react and then into public and then uploads and then we want to put the file name and it'll get moved there now if there's an error this takes in the second parameter of a call back with an possible error so we want to check for that for instance if the file does if the path doesn't exist then this is gonna run so I'm gonna do two things I'll console dot error just so we can see what it is and then let's also return res dot status 500 which is a server error and we'll just go ahead and send the error along alright now if there's no issues then we just want to res dot Jason which will send 200 response which is OK and as far as data I'm gonna send along the file name it's a file dot name and then also the file path so I'm gonna put back ticks and it's gonna be slash uploads slash and then the file name and that's it okay so that should do it for our back end now just to make sure this runs let's do npm run server and there it is alright so i'm gonna stop that and now we're going to move on to reacts so that that was the easy part so we're gonna go ahead and generate I'm gonna use npx create - react - app and we want to put it in the folder called client so that'll generate our react application inside a folder called client and we'll just clean some stuff up once this is done alright so as far as the files go I'm going to get rid of a bunch of this stuff serviceworker we don't need that logo index CSS app dot test we don't need any of this stuff so let's clear that out let's see inside index J s we're gonna get rid of this index CSS serviceworker and this stuff down here okay close that up inside app KS we want to get rid of the logo import also I'm going to be using hooks so there's no need to use classes I'm gonna actually get rid of this whole line right here and then the ending curly brace and then we'll turn the render into function called app so we're going to use an arrow function and we don't need this return statement we can return it directly so we'll get rid of that and then the ending curly brace okay and then as far as this header we don't need that we'll just say app for now all right so we'll save that another thing I want to do before we start the server is going to package Jason and add a proxy so right here make sure it's the react package Jason not the the Express or not the node one and we want to add proxy for our back-end which is HTTP local host port 5,000 all right so we'll go ahead and save that and then the very last thing I want to do before we run our server is installed Axios in our client because that's what we're going to be using to make requests so I'm going to CD into client and then npm install Axios okay make sure you CD into client don't install it on the back end alright so Axios is installed now make sure you CD dot dot back into the root here and then we can run NPM run dev which should run concurrently and run both the front end in the back end alright so you saw the back end said server started and now it's loading the react tab alright let's remove the initial CSS so this app dot CSS file I'm just going to clear that out all right so we have react up and running now let's let's bring in bootstrap so I'm gonna go to get bootstrap get started and grab the CSS and we're gonna go to our react public folder index.html and you can clear that up and just paste that in right there we might as well clear this crap up as well and I'm just gonna change the title to react file upload and let's grab the bootstrap JavaScript stuff which I don't I don't think we need but we might as well just put it in and then finally we want font awesome for that react logo that I'm using so grab that put that right above bootstrap all right so close that up and if we look at our application you can see the fonts change cuz bootstrap is now included all right now there's only a couple things we're doing in this main app file most of its going to be in the file upload component but within here first of all let's change this to class name to container so that it pushes everything to the middle and then I'm gonna do MT for to move everything down now I have prettier installed and I have auto auto format so when I save you might see some things change including if I have double quotes they change to single quotes it will format some stuff like semicolons so that's why alright so in here we're gonna do an h4 actually that's put some classes on this so display dash for text Center and MB for and then in this heading we want that react icon so we're gonna do eye with the class of fa b and a class of FA - react and then next to that icon we're just going to say react file upload okay and then underneath that h4 we're going to have our file upload component which we need to create so let's save this and take a look one thing I forgot is on the container class they also want mt4 just to push everything down so inside source let's create a folder called components and we're gonna have a file called file upload dot Jas now I'm using I'm using hooks so we're going to be using functional components and I have an extension called es 7 react Redux snippets which is right here which has a bunch of snippets we can use our shortcuts oops I closed the file so to generate a functional component we can do our ACF to use arrow function and within here we're gonna have pretty much everything except for the progress bar and the message component where those will be separate components that will take in props but all the state and everything is going to go in this so let's start to build out the UI a little bit we're gonna use a react fragment so let's bring in fragments and replace this div okay and then we're gonna have a form we don't need an action will add the on submit in a little bit so as far as the form goes I'm just gonna head to bootstraps docks here and go to components and then forms and then on the side over on the right file browser so I'm gonna grab this this is this is going to give us this file input and I'll paste that in a couple things the class we need to change the class name so I'll highlight the first one control D to highlight the next one and then the next one and change that to class name and this input field has to have a slash on the end so we'll go ahead and save that then we want the submit button so under the div here let's add in input the type of submit value upload and then let's add class name BTN BTN primary BTN block and let's do let's do MT for some margin top and then this class up here I actually want to add and be four just to give it some spacing also you can't have a four attribute in JSX so this has to be HTML 4 like that alright so we'll go ahead and save that and let's bring it into a BIS so we can actually see what it looks like so not form file upload alright then when you're going to put this right under the h4 okay I can't resolve file upload what I do Oh dot slash components all right so if we go back to our application it looks like this all right so let's um let's create some state okay we're gonna have a few pieces of state but I'm just going to do the stuff we need for now so we need the actual file when we select it that should go into state also the file name because I want this right here to be replaced with the file name so the way that we're gonna do that is with hooks with the use state hook so we need to bring that in all right and then above the return we're gonna go ahead and set some brackets here and we want file and then set file and we want to take that from use state and what this is is it's the state so you can kind of think of this as if you're not familiar with hooks when you have your state object in the class you might have you know something like file that's set to nothing and then to change it you would do this dot state and then you'd pass in file and change it well with hooks this file is this the default is going to go in here which is nothing and then instead of set state we just simply call set file to change that value so hooks are I'm really liking them they're really just clean looking in addition to file we want file name so let's do file name and then set file name and that default actually I'm gonna do choose file oops because I'm gonna put that as the label so in here I'll say choose file now I can replace this with the file name state okay so I'll go ahead and save that and we should still see the choose file here now we need to have a non change event for this input for this file so let's go ahead and add that so we'll say on change equals we could do we could put the two methods we need set file and set file name right in here but I'm just going to create a new method called on change and we'll go ahead and nest that in here and we want to call set file all right now set file is going to take in from this event parameter we can do a dot target and then we have files now with HTML file inputs you can do multiple files so this is actually like an array so we just want the first one since this is a single file upload okay so what the zero index now to set the file name I'll just copy this down and we'll do set file name and we want the same thing the same value here this object which has a property of name and we're gonna put that into this set file name so that will change this once we select it okay so I'm gonna save this and let's go back to our form and I'm going to open up my react dev tools and if I go to my file upload component you'll see down here under hooks we have our two pieces of state the file and the file name and once I choose a file that's gonna fire off the on change and now check that out we have this the file name and we have the object which we can't see from here but that has a bunch of values in it so that file object is what we want to send to our server so that's gonna happen in the submission so let's go back and let's go to our forum and let's say on submit we want to call on submit and we'll put that right here so we want to prevent default so the forum doesn't submit and then in order to send a file we need to we need to add it to our forum data so we have to actually create a variable I'm going to call it form data and set that to new form data which is just part of JavaScript this isn't react and then we're going to take our form data variable and append on to it file now this index right here pertains to in our back-end this right here so requests dot files dot file if I call that image this would be B dot image all right and then we just want to pass in the file which is in our state and we can access it at any time because we called it file up here all right so now we're ready to make our request so we need to bring in Axios and we're going to use a sink of weight so we're gonna label this a sink since this is an arrow function you want to put it on the right before the parameter here and then we're gonna wrap this in a try-catch all right so here we're gonna create a variable called res for response set it to a weight and then make our request so Axio stock post and we want to pass in slash upload since we added the proxy we don't have to specify localhost 5,000 want to add our form data and then we're gonna add another an options object here alright now I want to add a content type to the headers so this takes in headers object and that's gonna be content - type and I'm going to set that to multi-part - form - data all right now let's see we're gonna deal with the prot with the progress bar and the percentage and stuff within here but I don't want to do that just yet I just want to show you guys how to actually upload the file before we do that so that will make the request now when that's finished let's let's add another piece of state here for the uploaded file so we'll say set uploaded file set that to use state and that's going to be an object because remember what we're sending back from our server is this right here an object with the file name and the file path so that's what we should get back in return and we want to put that into this piece of state so let's go right under the the the request here and let's do will get risk we'll get res dot data and that's going to include the object we send back from the server so let's pull out file name and file path from res dot data okay and then we'll simply set the uploaded file with set uploaded file and we'll pass in an object with the filename and file path all right now if something goes wrong here if we get an error it's possible we could get a 500 error if for instance this doesn't exist this path or if they don't include the image we'll get a 400 hour so let's test for that let's see let's say if and then this error object is gonna have a response dot status and we'll check for 500 if it's 500 then for now let's just console.log and say there was a problem with the server okay else then let's console.log error dot response dot data and remember we sent that msg value if it's 400 so right here msg that's what I'm grabbing all right and later on this is gonna be outputted in an alert but for now we're just gonna console.log like I said I just want to get the upload done so that should do it I believe as far as being able to actually upload so let's save that and yeah I guess yeah let's try it out so we'll go back here let's make sure we have no console errors here that's fine actually component in our app dot J s we don't need this anymore because we're not using a class okay so let's try this we'll browse and grab test one let's upload okay so we got there is a problem with the server now if we look in our console down here you can see that it's telling us that this path doesn't exist so in client public there's no uploads folder so let's create that alright so now let's reload and try this again let's go ahead and upload all right so nothing happened but it did upload we should have got a console log though yeah we should have got a console log it did upload there it is oh no we shouldn't have got a console log it just set the uploaded file I didn't put a log here that was only if there was an error alright good so it works as expected now we want to show the image after we upload it so it should be inside of this state right here uploaded file so all we have to do is go down to our render down here or our return I should say and let's go under the form and we need to do a conditional so we're going to use a ternary we're gonna say if uploaded file then let's put in let's do a div actually let's do div and I'm going to use the bootstrap grid just to kind of narrow it down into the middle a six column div so I'm gonna do a row let's do row and inside here next let's move it down a little bit so we'll do MT 5 and then inside the row we're gonna have a class of call MD 6 and M dash Auto which we'll move it to the middle and then in here let's put in a ch3 with the class of text center and I want to put the file name so we can access that with uploaded file which is our state and remember it has that file name that's getting sent back and put into that object okay so we get the file name and then underneath let's do an image and for the source we're just going to put in here uploaded file dot file path and I just want to add some a little bit of inline styling so style equals double curly braces and I'm gonna set the just gonna set the width to a hundred percent of its container all right so we'll save that now this only should show if the uploaded file is there and let's see I'm getting an error oh I didn't do an else so I did if uploaded file ternary show this now we need to do else then No all right so that should work so let's go back and now I can upload the same file and there we go now like I said the the focus of this is the front end if you want to go in the back end and you want to rename the files and stuff you could do that pretty easily if you want to check to make sure it's an image you can do that and then send a response I might add that to the github later but I don't want to make this tutorial too long so I'm not gonna deal with that cuz we're mostly focusing on the front end here alright so now that that's done let's do let's see let's do our alert our message okay we want to have a message if there's an error also after it's uploaded it should say that it's been uploaded so I'm gonna go back to file upload and add another piece of state here I'll just copy this down and this is going to be a message which by default would just be nothing so we'll call this message and say set message and hopefully you can see how elegant hooks are if you haven't used them yet so we have the set message and there's a couple places we're gonna want to set a message so one is after it's done so I'm gonna go after the set uploaded file and do set message because everything worked out so we'll say file uploaded all right and then in the error let's change both of these to set message all right now these will just put it in the state they're it's not actually gonna show so I'm gonna just save this and create a new component called message dot J s and let's do our ACF P which will also give it prop types because we're screwing it we're gonna pass in the message so let's do msg as a prop type I'll say PT and it's going to be a string so pts and it's required this extension is really cool this es7 react snippets so let's see for the props we're just going to do some destructuring and just pull out msg and as far as the the ASX it's gonna be a bootstrap alert so I'm going to grab from alerts I want a dismissable alert which is just sit yeah right here so I'm gonna grab that copy it place this and let's change class to [Music] classname I'm also gonna I don't want warning I want info which is blue and then we're gonna replace this this dummy text here with the MSG prop alright so I think that's good let's save it yeah so that should work yeah so let's let's bring that into our file upload okay and we just want to go down in our return wherever we want to put this which is gonna be at the very top so right under fragment we're gonna say if there's a message state then show the message component and pass in MSG which will be equal to whatever our messages okay else then no don't show anything all right so let's go back and let's try to submit without anything and we get no file uploaded and we're getting that 400 bad request from our server alright cool if we I'm trying to think of call how we can cause another error if we get rid of the uploads folder let's just delete it completely and we submit actually I guess well yeah there's no file uploaded so let's choose a file we still should get an error and we get there was a problem with the server so that's that's how it should work so I'm gonna put that folder back in public uploads and now let's do a successful upload so I'll reload and grab that image upload and we get file uploaded perfect we can close that up alright so now what I want to do is add the progress bar so within Axios okay so back in file upload where we made our request this third parameter this options okay underneath this header we can actually add in this upload progress function so I'm gonna put a comma right here and we're gonna say on upload progress you can see it drop comes down here in the intellisense and we're gonna use an arrow function this is gonna take in progress event progress event and an arrow now I'm gonna have another piece of state this would be our final state and it's gonna be upload percentage okay so we'll say set upload percentage and set that to use state and the default for that is going to be zero so this will actually give us this this progress event will give us loaded so dot loaded and dot total so what's been loaded in what's total so we need to do a little bit of math to get the actual number of percentage so we're gonna set we're gonna do set upload percentage okay to set our state and we're gonna do parse int so that it's a number and we need to do math dot round and we need to pass in another set of parentheses with progress event progress event we want the loaded value and we want to multiply that by a hundred okay then we want to go outside that parentheses and divide by progress event dot total and that will give us the actual number percentage okay now we're gonna we're gonna have that progress bar that fills up and what I want to happen is after ten seconds I want it to clear you don't have to do this I just thought that it was a good addition to the UI just so it doesn't stay at a hundred percent so let's say clear percentage so to do that we just again just call set up load percentage except we're just going to pass in zero actually what I forgot to do here is set time oh so because we want it to delay so we're gonna do set timeout and then we're gonna pass in a function it takes in a function and then do set upload percentage and set that to zero and we want to do that after 10 seconds so 10,000 milliseconds oh you know what what'd I do wrong here upload progress let's see what the hell they do wrong unexpected token expected comma oh this should be autumn this should be within this method here like that there we go alright so that we'll get rid of it after ten seconds now we don't have the progress bar yet but we should be able to see it within our state in the react dev tools so if we look at file upload and we look at our state just absolute mean to do that if we look at our state with a zero right here is the the percentage so what I'm gonna do is grab a file and once I hit upload you can see that it went to a hundred it goes very fast but it goes from zero to 100 so now we can use that that piece of state to pass it into a progress bar component and make that reflect whatever that percentage is so let's do that let's create a new component called progress j/s and let's let's do our a CFP and if you don't have that extension just type this stuff out it saves a lot of time it's going to have a prop of percentage and that's gonna be a number so prop type number required and as far as the props are gonna be structure that and pull out the percentage all right so I'm just gonna grab a progress bar so it's progress I'm going to grab the green striped one which is this one here so we'll grab that you know grab that down here change the classes to class name all right now obviously we need to make this dynamic I also want to have the label in here so inside here we can put in our percentage prop and then a % and then for the for the style here let's get rid of these for the style we're gonna change that to double curly braces and we want to set the width to a set of back tics and then we want the percentage okay that whatever's passed in and then just the percent of % and that will change the actual length of the progress bar so let's save that and let's go back into file upload and bring that in okay now where we want to put this is let's see we're gonna put this right below the not the form but the input so this div ends right here so in between the dis div and the in submit button we're gonna put this so let's do prog progress okay now it needs to take in a prop and it's gonna take in percentage and that's going to be equal to the upload percentage whatever is in that state which by default is 0 and then it will fill up when we do the upload so let's save that and let's go back okay there we go zero percent and let's upload an image upload test2 and there we go looks like this is not right though how I have this label let me see because the the one up here right here labels actually no it's right isn't it let me check class the hell I don't see anything wrong with that oh yes I do this div right here shouldn't be self-closing it needs to have an ending div and then the percentage goes in here so we want to take that and we want to move that up in there all right okay so let's browse there we go so now the label looks correct all right cool so and this should go away after 10 seconds let's make sure that happens and again you don't have to do that I just thought it was a nice effect all right so we're now uploading our files if we look in uploads we have test1 and test2 and like I said if you want to rename them so that people can upload images of the same name you can easily do that in your server j/s all right so that's gonna be it guys I know this was kind of a long video especially if you were just looking for a simple you know how to upload an image but I wanted to actually create this this little application here and have some cool effects so hopefully you enjoyed it if you did please leave a like and that's it I will see you next time
Info
Channel: Traversy Media
Views: 210,814
Rating: undefined out of 5
Keywords: react, file upload, react file upload, node.js file upload, react image upload
Id: b6Oe2puTdMQ
Channel Id: undefined
Length: 45min 1sec (2701 seconds)
Published: Wed Apr 10 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.