Coding

React Image Upload Made Easy

  • 00:00:01 welcome to this video where I want to
  • 00:00:03 have a look at how we can upload files
  • 00:00:05 to our back-end to some restful api
  • 00:00:08 weather react app or in a react app so
  • 00:00:12 let's dive right into that
  • 00:00:16 I'm in a brand-new project which I
  • 00:00:18 created with create react app didn't
  • 00:00:21 change anything in there and I'm in the
  • 00:00:23 app.js file which is the main component
  • 00:00:25 we're viewing here once we start the
  • 00:00:27 development server now in there I'll
  • 00:00:29 first of all get rid of all the content
  • 00:00:31 and I'll start simple I want to add an
  • 00:00:33 input a file input which the user can
  • 00:00:36 use to pick a file so I'll actually add
  • 00:00:38 an input of type file here just like
  • 00:00:42 that should be a self-closing of course
  • 00:00:44 now if I save this what we can see is
  • 00:00:47 this well file input here unsurprisingly
  • 00:00:49 in which I can pick a file now I want to
  • 00:00:52 see which file was picked so in order to
  • 00:00:55 do this I'll add the on change listener
  • 00:00:57 which will fire whenever the user
  • 00:01:00 changes and you changes the file picks a
  • 00:01:02 new file so add a method here which I'll
  • 00:01:05 simply name file selected Handler where
  • 00:01:09 I will get the event and where for now I
  • 00:01:11 simply want to lock that event
  • 00:01:14 so with that I'll assign it here with
  • 00:01:18 this file selected Handler and please
  • 00:01:21 note I'm using that syntax where I set
  • 00:01:24 up this method as basically a property
  • 00:01:26 that holds the arrow function this will
  • 00:01:29 ensure that this keyword inside that
  • 00:01:31 method always keeps the context of this
  • 00:01:34 component and doesn't refer to anything
  • 00:01:36 else as it often does if you attach
  • 00:01:39 event listeners so now with that let's
  • 00:01:42 go back to the app and let's actually
  • 00:01:44 choose a file now and you see I get this
  • 00:01:48 event which gets executed where I also
  • 00:01:50 got the target wrapped in there now I'm
  • 00:01:54 interested in that target so I will
  • 00:01:56 execute
  • 00:01:56 event target and lock that to the
  • 00:01:59 console so let's try this again and now
  • 00:02:04 we see we get that fall input now the
  • 00:02:06 cool thing is on there since it is a
  • 00:02:08 file input will have a files array where
  • 00:02:12 the first element will be the file we
  • 00:02:15 added and if we had a multi file input
  • 00:02:17 field here we could access all the files
  • 00:02:21 here as elements of that array so now
  • 00:02:23 I'm logging that first foul if I do it
  • 00:02:25 like this then this is the file the user
  • 00:02:28 picked with the name the size and so on
  • 00:02:31 this is the file I want to upload
  • 00:02:33 obviously I could upload whatever
  • 00:02:35 default changes or I simply add a button
  • 00:02:38 below there a button where I say upload
  • 00:02:41 and where I then will add a click
  • 00:02:45 listener so here I'll add on click and
  • 00:02:48 execute my let's say this file upload
  • 00:02:52 handler now I need to add this so we'll
  • 00:02:55 add my file upload handler method here
  • 00:02:58 don't need an argument and in here the
  • 00:03:01 goal is to upload the file the for that
  • 00:03:04 I need to store it so I will initialize
  • 00:03:07 my state here although with this
  • 00:03:09 properties syntax where I have to select
  • 00:03:13 a file which initially is just now let's
  • 00:03:15 say here where we select the file I will
  • 00:03:19 no longer log it but instead called this
  • 00:03:21 set state and set my selected file equal
  • 00:03:25 to event target files and that first
  • 00:03:27 fall we selected now it's stored in my
  • 00:03:29 state and now we can use it here in the
  • 00:03:32 upload handler but for uploading we need
  • 00:03:35 to send an HTTP request and I want to
  • 00:03:37 use a library for that I will use
  • 00:03:40 Axios to send that request so I quit my
  • 00:03:43 development server and I will install
  • 00:03:45 with NPM install – – save or actually
  • 00:03:48 here I will use yarn because that was
  • 00:03:50 initialized with yarn so yarn add Axios
  • 00:03:53 or NPM install – – safe access would be
  • 00:03:57 equivalent thereafter I'll start
  • 00:04:00 development server again and now I can
  • 00:04:03 import Axios from Axios here and use
  • 00:04:07 that package in the file upload handler
  • 00:04:10 I can then call Axius post and post my
  • 00:04:16 request to a certain URL now for the URL
  • 00:04:20 I will use an endpoint I created with
  • 00:04:22 the help of a firebase cloud function I
  • 00:04:25 did this in an earlier video you can
  • 00:04:27 find on this channel link is in the
  • 00:04:29 video description and probably up here
  • 00:04:30 and in this video you will learn how you
  • 00:04:33 can setup your own API endpoint with the
  • 00:04:36 help of firebase cloud functions and
  • 00:04:38 there I created an API endpoint that
  • 00:04:40 accepts incoming foreign data so a
  • 00:04:43 mixture of
  • 00:04:44 Fields and files and stores the file
  • 00:04:46 this might hold in firebase cloud
  • 00:04:49 storage to see this in action I'll go to
  • 00:04:54 the firebase console where I edit this
  • 00:04:55 and I'll first of all clean up my file
  • 00:04:57 storage so that it's empty so that we
  • 00:04:59 can really see if that worked and then
  • 00:05:02 the function has this endpoint
  • 00:05:05 now you can't use that because the
  • 00:05:07 project will not be available anymore
  • 00:05:09 when you're watching this but you can
  • 00:05:11 create this as I show in the other video
  • 00:05:13 or of course you use any other backhand
  • 00:05:16 you might have so with that I'll go back
  • 00:05:19 to my app and add this URL and now I
  • 00:05:23 want to construct some form data which I
  • 00:05:25 send so name this FD new form data
  • 00:05:28 that's a default JavaScript object and
  • 00:05:31 there will append let's say my image
  • 00:05:34 field you can name this whatever you
  • 00:05:35 want I will get my selected file from
  • 00:05:39 the state and give it the name the file
  • 00:05:41 has by accessing this state selected
  • 00:05:45 file and there the name property you
  • 00:05:47 could see this earlier in the console
  • 00:05:49 lock that the file has this name
  • 00:05:50 property and with that this is the data
  • 00:05:53 I want to send with the post request so
  • 00:05:56 we'll set this as data which should be
  • 00:05:58 sent and thereafter this gives us a
  • 00:06:01 promise where I want you output any
  • 00:06:06 response I get here we can also add a
  • 00:06:09 catch block to catch errors but let's
  • 00:06:12 first of all see if this succeeds like
  • 00:06:13 this so now I save that and I go back to
  • 00:06:17 my app and it will now choose a file
  • 00:06:20 where we don't upload it yet we just
  • 00:06:22 selected it but if I now press upload we
  • 00:06:26 should after a short duration see our
  • 00:06:29 response and that's looking good 200 and
  • 00:06:32 if we have a look at the data we get it
  • 00:06:34 worked which indeed is the response this
  • 00:06:36 firebase function gives back if
  • 00:06:38 everything works so that's pretty cool
  • 00:06:40 and this is already how you can upload
  • 00:06:42 files from your react there just like
  • 00:06:44 that very simple we can enhance this
  • 00:06:47 with Axios we can also report the
  • 00:06:51 progress of the file upload by passing a
  • 00:06:54 third argument to configure this request
  • 00:06:56 and they
  • 00:06:57 you can add a on upload progress handler
  • 00:07:01 there it will then execute this function
  • 00:07:04 where we get the progress event which we
  • 00:07:07 can use for example to update GUI and
  • 00:07:09 output a percentage of the upload state
  • 00:07:12 here I will simply log it to the console
  • 00:07:14 and there we can say upload progress and
  • 00:07:19 then simply add the progress event and
  • 00:07:22 there will have a loaded property which
  • 00:07:25 is the amount in kilobytes or in bytes
  • 00:07:27 that has already uploaded divided by
  • 00:07:30 progress event total which will be the
  • 00:07:32 total amount it has to upload that's
  • 00:07:34 just what this event exposes to you
  • 00:07:37 this event is coming from the
  • 00:07:38 xmlhttprequest object behind the scenes
  • 00:07:41 now we can wrap this in parentheses and
  • 00:07:46 multiply it with 100 like this and maybe
  • 00:07:52 then round the overall result so
  • 00:07:54 math.round whoops times 100 should be
  • 00:07:57 inside the parentheses though so that we
  • 00:08:00 round the overall value to the next
  • 00:08:02 integer and then we could add percent
  • 00:08:06 after that now let's see this in action
  • 00:08:09 let's save this and let's again pick a
  • 00:08:12 file here and click click upload and now
  • 00:08:16 you see we got the different progress
  • 00:08:18 events in between and then it takes a
  • 00:08:20 little bit longer to get back response
  • 00:08:22 and we get the response and with that we
  • 00:08:25 enhance this upload and of course you
  • 00:08:27 could use the data you get back on the
  • 00:08:30 progress event to update your progress
  • 00:08:32 bar or whatever you have on your page
  • 00:08:34 know one last thing I want to do in this
  • 00:08:36 video I want to make sure that we also
  • 00:08:39 learn how we can hide this input and
  • 00:08:42 trigger it through some button in case
  • 00:08:44 you don't want to show that input you
  • 00:08:47 can then simply set some inline styles
  • 00:08:49 here and set this play to non like this
  • 00:08:53 and then maybe add another button where
  • 00:08:57 you say pick file where I will then
  • 00:09:02 simply add onclicklistener and now I
  • 00:09:05 want to essentially trigger this input
  • 00:09:07 when this button is clicked for this I
  • 00:09:11 use a concept and react named refs a ref
  • 00:09:14 is simply a way for me to get access to
  • 00:09:17 another reference in my Dom in my
  • 00:09:19 template here in the JSX code I should
  • 00:09:22 say I use it by adding the ref key here
  • 00:09:25 and ref then takes a function where we
  • 00:09:29 find some property of our class – a
  • 00:09:32 reference of this input so here maybe I
  • 00:09:35 could name this file input and set this
  • 00:09:39 file input equal to file input so react
  • 00:09:43 will give me a reference to this file or
  • 00:09:44 to this input excuse me to this element
  • 00:09:46 and I can then store this in a property
  • 00:09:48 of this class and now in on click I can
  • 00:09:50 simply execute this file input click
  • 00:09:54 this should be wrapped into a method
  • 00:09:56 though so let me quickly do that let's
  • 00:09:59 create an arrow function which will then
  • 00:10:00 execute this now if dad if I save that
  • 00:10:03 and go back you see the input element is
  • 00:10:06 hidden but if I click pick file it still
  • 00:10:08 opens and it still works as before but
  • 00:10:12 now through that button and by hiding
  • 00:10:14 that input element which might be
  • 00:10:16 something you want you don't need to do
  • 00:10:17 that it's just an option and I hope this
  • 00:10:20 video was helpful and with that file
  • 00:10:21 uploads are a bit easier in a bit
  • 00:10:23 clearer when it comes to implementing
  • 00:10:25 them in a react app