Coding

Sending JavaScript Http Requests with the fetch() API

  • 00:00:00 this is the second video in a short mini
  • 00:00:03 series of free videos where I have a
  • 00:00:05 look at common ways were of typical ways
  • 00:00:08 of sending HTTP requests in a front-end
  • 00:00:12 JavaScript application to a back-end in
  • 00:00:14 the previous video which you should
  • 00:00:16 absolutely check out link below the
  • 00:00:18 video of course we had a look at XML
  • 00:00:21 HTTP requests in this video we'll have a
  • 00:00:23 look at the fetch API it is better than
  • 00:00:27 XML HTTP requests in some aspects but in
  • 00:00:30 some aspects it's all the worse and I'm
  • 00:00:34 just talking about the basic
  • 00:00:35 functionality so let's have a look at
  • 00:00:38 how it generally works and see how you
  • 00:00:40 can use the fetch API in your projects
  • 00:00:46 so now I want to rebuild with the fetch
  • 00:00:49 API what I already built with
  • 00:00:51 xmlhttprequest in the previous video now
  • 00:00:55 definitely check out that video if you
  • 00:00:56 haven't already of course therefore in
  • 00:00:59 there we used xml httprequest in a
  • 00:01:01 utility function and we promised a fide
  • 00:01:03 it by wrapping it with a promise so that
  • 00:01:06 we can send a get in a post request
  • 00:01:08 append data and also handle errors we
  • 00:01:11 also made sure we attach to write header
  • 00:01:13 now we'll rebuild the same thing with
  • 00:01:16 the fetch API so for that let's start
  • 00:01:18 with the get request the fetch API is a
  • 00:01:21 relatively modern addition to the
  • 00:01:24 browser and not all browsers support it
  • 00:01:26 especially older browsers Internet
  • 00:01:29 Explorer of course does not support it
  • 00:01:31 so if you need support for dad and you
  • 00:01:33 don't want to add a polyfill or anything
  • 00:01:35 like that you should use XML HTTP
  • 00:01:37 request here however I'm working in
  • 00:01:40 chrome so I'll use the fetch API and we
  • 00:01:42 can use it by calling fetch this is a
  • 00:01:45 globally available function made
  • 00:01:47 available by the browser in JavaScript
  • 00:01:49 and you can use it to send a HTTP
  • 00:01:51 request now we're using the request
  • 00:01:54 dummy API here and in there you get a
  • 00:01:57 couple of dummy endpoints to which you
  • 00:01:59 can send requests they're not returning
  • 00:02:01 real data and you can't create real data
  • 00:02:03 there but you can fake all these
  • 00:02:05 operations and here I want to get a list
  • 00:02:08 of users for that we can send a get
  • 00:02:10 request to this URL which is exactly the
  • 00:02:13 same thing we did with the XML HTTP
  • 00:02:15 request so it's this URL I want to send
  • 00:02:17 the request to and therefore here on the
  • 00:02:20 fetch function we just have to pass in
  • 00:02:22 that URL now without any additional
  • 00:02:26 configuration this will send a get
  • 00:02:29 request to that URL which is exactly
  • 00:02:31 what I want now fetch unlike XML HTTP
  • 00:02:36 request by default uses promises so
  • 00:02:38 without any extra work without wrapping
  • 00:02:41 it with a promise manually we can add a
  • 00:02:43 then method here and utilize our
  • 00:02:45 response now if we console lock the
  • 00:02:49 response here let's see what we get if
  • 00:02:51 we save that and we then make sure in
  • 00:02:54 index.html that we import fetch jeaious
  • 00:02:58 here instead of xhr jeaious
  • 00:03:00 we can go back to our little application
  • 00:03:02 here simply opened with a double click
  • 00:03:04 we need no def server for that if we now
  • 00:03:07 reload that and click get data we get
  • 00:03:10 our response object now in that object
  • 00:03:12 we get a couple of interesting features
  • 00:03:14 get the status code whether the response
  • 00:03:17 was treated as ok so if it was
  • 00:03:19 successful has a 200 ish status code
  • 00:03:21 essentially we got the URL we got some
  • 00:03:24 headers that were part of the response
  • 00:03:25 and we got the body and now the body is
  • 00:03:28 a readable stream that's not too great
  • 00:03:30 because we can't really work with a
  • 00:03:32 readable stream here I want the snapshot
  • 00:03:35 I want to snap shut off the returned
  • 00:03:37 data I want data which this request
  • 00:03:40 should actually return which should look
  • 00:03:42 like this now for dead the fetch API has
  • 00:03:47 a utility method we can call on the
  • 00:03:49 response object and that's response dot
  • 00:03:51 jason if the response body should be
  • 00:03:54 json data which it should be for this
  • 00:03:57 dummy api then this will convert the
  • 00:03:59 stream body to streamed body into a
  • 00:04:02 snapshot and automatically parse JSON
  • 00:04:04 data to native javascript datatypes if
  • 00:04:08 you have a different data format let's
  • 00:04:12 say text you also have a text method
  • 00:04:13 which transforms the stream to a
  • 00:04:15 snapshot and does not do the JSON
  • 00:04:18 parsing for example and you get a couple
  • 00:04:19 of other methods as well so we need to
  • 00:04:21 call this to convert our streamed body
  • 00:04:24 into a snapshot and to also then as a
  • 00:04:27 extra convenience convert to json data
  • 00:04:29 to javascript datatypes
  • 00:04:31 now the jason method itself returns a
  • 00:04:34 promise so we can return the result of
  • 00:04:37 this and add another then method to this
  • 00:04:40 promise chain in promises or when
  • 00:04:43 working with promises we can chain
  • 00:04:44 multiple then methods to execute
  • 00:04:46 multiple steps and this return promise
  • 00:04:50 here is basically merged with this main
  • 00:04:52 promise chain and in the next ven block
  • 00:04:54 we therefore have access to the result
  • 00:04:57 this promise the promise created by the
  • 00:04:59 jason method resolves – which will be
  • 00:05:02 our response data here so the response
  • 00:05:06 data is now the interesting part let's
  • 00:05:09 login and see if this is now the data we
  • 00:05:12 expect
  • 00:05:13 if we save that and we now reload and
  • 00:05:15 click on get data this looks much better
  • 00:05:18 so this is actually all we need for
  • 00:05:20 getting the data you could of course now
  • 00:05:22 render this on the screen that's not
  • 00:05:24 really what I want to show here instead
  • 00:05:26 this is how we can use the fetch API
  • 00:05:27 here and how we can get data transform
  • 00:05:31 it and use it now let's all make sure we
  • 00:05:34 can send data now for dead we can of
  • 00:05:37 course duplicate this code here and just
  • 00:05:42 make sure we send a post request there
  • 00:05:44 now just as with the XML HTTP request
  • 00:05:47 I'm not the biggest fan of code
  • 00:05:48 duplication though at least with the
  • 00:05:50 fetch API we have less overhead we don't
  • 00:05:53 have all these extra steps we had with
  • 00:05:54 xml httprequest so i think it would be
  • 00:05:57 fine to indeed execute it again like
  • 00:06:00 this without any wrapping utility
  • 00:06:03 function nonetheless I want to create
  • 00:06:05 one I'll name it send HTTP requests here
  • 00:06:08 as well and this should be a function
  • 00:06:10 that takes a method and a URL and data
  • 00:06:14 that should be attached and in there I
  • 00:06:16 want to send the fetch request return
  • 00:06:19 the result of that and now of course
  • 00:06:21 exchange this URL for the URL argument
  • 00:06:24 here and then also make sure we later
  • 00:06:27 utilize the method ends on now first of
  • 00:06:29 all here with get data I therefore want
  • 00:06:31 to call send HTTP request here when I
  • 00:06:34 send a get request here of course and
  • 00:06:37 then to this URL and now regarding the
  • 00:06:40 handing of the response I think this
  • 00:06:42 extraction of the response body that's
  • 00:06:44 something that fits quite well into this
  • 00:06:46 utility function but of course what we
  • 00:06:48 do with the response data should not go
  • 00:06:50 in there so I'll remove that last step
  • 00:06:52 in the utility function and here when we
  • 00:06:55 call send HTTP request we therefore can
  • 00:06:57 get rid of that response data extraction
  • 00:07:00 step and we get the response data right
  • 00:07:03 away because we do the extraction in the
  • 00:07:05 utility function so we have that now we
  • 00:07:08 have our response data which we log now
  • 00:07:11 and let's verify that this still works
  • 00:07:13 by reloading and clicking on get data
  • 00:07:15 looks good
  • 00:07:16 and now we can utilize send HTTP request
  • 00:07:19 also here when we try to send data here
  • 00:07:22 i want to send a post request and the
  • 00:07:25 URL
  • 00:07:27 actually should be this register URL
  • 00:07:31 here so API slash register and they
  • 00:07:35 offer here I'll copy that URL but I'll
  • 00:07:40 change users here for register now here
  • 00:07:44 we also want to append some data and
  • 00:07:46 that can be a JavaScript object here now
  • 00:07:48 to get a success response as we learned
  • 00:07:51 in the last video we have to send
  • 00:07:53 exactly this data here so I'll copy that
  • 00:07:55 copy that into my object however
  • 00:07:58 converted to normal JavaScript object we
  • 00:08:01 don't need the quotes around the object
  • 00:08:04 keys here
  • 00:08:04 and once that we should be good almost I
  • 00:08:08 also want to handle any response data
  • 00:08:11 we're getting back so that we can see
  • 00:08:13 whether we succeeded or not like this
  • 00:08:15 and with that we just need to tweak send
  • 00:08:19 HTTP request to make sure that in there
  • 00:08:22 we do utilize the method and the data
  • 00:08:25 because right now that is not happening
  • 00:08:27 right now we're always just sending a
  • 00:08:29 get request now to tweak that request we
  • 00:08:32 can pass a second argument to fetch this
  • 00:08:35 is an object that allows us to configure
  • 00:08:37 the outgoing request if you hit control
  • 00:08:39 space here in visual city code you see
  • 00:08:42 there are a bunch of things you can
  • 00:08:43 configure a lot of niche options which
  • 00:08:45 you don't need it often but for example
  • 00:08:48 you can set the method and that by
  • 00:08:50 default is set to get and therefore you
  • 00:08:53 don't need to set it if you always want
  • 00:08:54 to send a get request but here I wanna
  • 00:08:56 set it to method so to the argument
  • 00:08:59 value I'm getting here so that we are
  • 00:09:01 able to dynamically set us and to either
  • 00:09:03 send a get or maybe also a post request
  • 00:09:06 now we also can add body here to attach
  • 00:09:10 a body to the outgoing request
  • 00:09:13 now the body here should be JSON data
  • 00:09:16 and therefore all json stringify the
  • 00:09:19 data package we're getting this might be
  • 00:09:21 undefined like in this scenario here but
  • 00:09:24 then we just don't add any body and we
  • 00:09:26 don't need any body for a get request
  • 00:09:28 and the effort this shouldn't be a issue
  • 00:09:30 so now we have the body which is added
  • 00:09:32 here and with that we're almost there in
  • 00:09:35 the last video we also learned that we
  • 00:09:37 need to attach a header the content type
  • 00:09:40 header
  • 00:09:40 to make sure the API doesn't fail and
  • 00:09:43 hence we should do this here as well for
  • 00:09:45 that we can add a headers object and now
  • 00:09:48 I want to see I want to check if data is
  • 00:09:50 set with a ternary expression if it is
  • 00:09:53 true C then header should be an object
  • 00:09:55 that includes a content type key where
  • 00:09:59 the value is application slash
  • 00:10:03 Jason otherwise I want to add an empty
  • 00:10:06 object and this basically is how you add
  • 00:10:09 headers with the fetch API you can have
  • 00:10:11 as many key value pairs here as you want
  • 00:10:13 in this object and they will be appended
  • 00:10:15 as headers to the outgoing request here
  • 00:10:18 I'm using the content type header with
  • 00:10:21 this default value otherwise if data is
  • 00:10:24 faulty I'm setting this to an empty
  • 00:10:26 object which means I don't add any
  • 00:10:28 special headers so now this should be
  • 00:10:31 more flexible and if we now check this
  • 00:10:33 with that data we found on the official
  • 00:10:36 docks after saving everything if we
  • 00:10:38 reload this page and we click on post
  • 00:10:40 data that's looking quite good that is a
  • 00:10:43 success response now let's also simulate
  • 00:10:46 an error and to do that we can comment
  • 00:10:49 out the password so that we don't send
  • 00:10:51 the password data if we do that and we
  • 00:10:54 save it and reload if we now click post
  • 00:10:57 data we get an error here the problem is
  • 00:11:00 we still get the log from line 25 which
  • 00:11:03 means we still make it into this success
  • 00:11:05 then block so maybe try adding catch
  • 00:11:09 here write add catch catch any potential
  • 00:11:12 error and then maybe lock this error
  • 00:11:14 here of course you could implement more
  • 00:11:16 sophisticated error handling here now if
  • 00:11:19 we do that let's see if we now get some
  • 00:11:21 output from line 29 let's reload and
  • 00:11:25 click post data and we don't we get it
  • 00:11:28 from line 26 which still is our success
  • 00:11:31 case this is exactly the same problem in
  • 00:11:35 quotes because it's actually the
  • 00:11:36 intended behavior we saw in the last
  • 00:11:38 video with xml httprequest errors which
  • 00:11:43 are not technically errors which means
  • 00:11:45 errors which are not related to network
  • 00:11:48 issues or anything like that but errors
  • 00:11:50 where we get a successful response where
  • 00:11:52 we just have a non success status code
  • 00:11:55 400 or 500 are treated as successful
  • 00:12:00 responses by the fetch API and the same
  • 00:12:02 was the case for xml httprequest so we
  • 00:12:06 make it into the success handlers so to
  • 00:12:09 say even if we have a error status code
  • 00:12:12 because technically it's a valid
  • 00:12:14 response the requests left our
  • 00:12:17 application without issues and we got a
  • 00:12:19 response without issues which is why no
  • 00:12:22 error is thrown by default now of course
  • 00:12:25 we nonetheless have a error case here
  • 00:12:29 we're not happy with the result we have
  • 00:12:31 an error which we want to handle now for
  • 00:12:34 that we can do something similar as
  • 00:12:36 before in the success handler we want to
  • 00:12:38 check the status code now thankfully
  • 00:12:41 here in our send HTTP request function
  • 00:12:44 the response object has a status
  • 00:12:47 property which we can check and this
  • 00:12:50 gives us the status code and if that is
  • 00:12:52 greater or equal than 400 then we're not
  • 00:12:54 happy with the response an alternative
  • 00:12:57 would have been to check the response
  • 00:13:00 dot okay field which is true for
  • 00:13:02 successful responses so for 200 ish
  • 00:13:05 codes and false otherwise but this will
  • 00:13:08 work as well so if this is greater or
  • 00:13:11 equal than 400 we know excuse me here we
  • 00:13:13 should have checked for naught okay so
  • 00:13:15 here if we are have a code greater than
  • 00:13:17 400 or equal to 400 then we have an
  • 00:13:19 error an error status code so here we
  • 00:13:23 want to basically throw it error and if
  • 00:13:26 we throw an error here in a venn block
  • 00:13:28 this will effectively reject the outer
  • 00:13:31 promise so that in the promise chain
  • 00:13:34 where we listen to the outer promise we
  • 00:13:36 would make it into a catch block so here
  • 00:13:38 we can throw a new error and maybe you
  • 00:13:43 say something went wrong but maybe we
  • 00:13:46 also want to add some extra content to
  • 00:13:49 the error so actually I want to create
  • 00:13:51 an error object here with new error
  • 00:13:55 something went wrong where I add extra
  • 00:14:00 data which should be my response body
  • 00:14:02 and now that's where we have a problem
  • 00:14:03 with the fetch API the response body is
  • 00:14:06 not available in this step
  • 00:14:09 learned we have to parse it and error
  • 00:14:11 responses are no difference because
  • 00:14:13 technically they're exactly the same
  • 00:14:15 kind of responses as success responses
  • 00:14:18 so the body at this point here in this
  • 00:14:21 Venn block here is that streamed body
  • 00:14:24 not the snapshot so if I want to attach
  • 00:14:26 the response body here that's just not
  • 00:14:29 possible now that's of course pretty
  • 00:14:31 annoying what can we do to mitigate that
  • 00:14:34 well we can cut that code for now and in
  • 00:14:39 that if case here we could actually call
  • 00:14:43 response JSON which gives us a promise
  • 00:14:45 and now add a Venn block here therefore
  • 00:14:48 we have a nested promise chain in this
  • 00:14:51 outer promise chain which is never that
  • 00:14:53 great but here actually it's a good
  • 00:14:55 solution where we now will have our
  • 00:14:57 error response data so to say and now in
  • 00:15:01 here we can create our error assign the
  • 00:15:04 error response data to the data property
  • 00:15:07 of the error and then fro error and now
  • 00:15:10 we just need to return this inner
  • 00:15:12 promise chain here so that it becomes
  • 00:15:15 part of that outer promise chain because
  • 00:15:18 if we return something in that promise
  • 00:15:20 chain we merge it into the promise chain
  • 00:15:22 so to say there's something we return
  • 00:15:24 here itself is in the end a promise
  • 00:15:27 which is rejected because we throw an
  • 00:15:30 error inside of it so that's what we do
  • 00:15:33 here in the error status code case since
  • 00:15:36 we returned we need no else statement
  • 00:15:38 and otherwise we just return Jason like
  • 00:15:41 that so now we either return a promise
  • 00:15:44 that will throw an error or we return
  • 00:15:47 the body data this is how we can handle
  • 00:15:49 it but we need this extra inner this
  • 00:15:52 wrapped promise chain here because of
  • 00:15:56 the way the body has to be parsed with
  • 00:15:58 the fetch API with that however we
  • 00:16:01 should make it into this catch block
  • 00:16:03 here if we do have an error and
  • 00:16:04 therefore if we reload and click post
  • 00:16:06 data now we get output from line 37
  • 00:16:10 something went wrong which is my custom
  • 00:16:12 message so that looks good in line 37
  • 00:16:14 now indeed is the catch block and here
  • 00:16:17 we could also access error dot data and
  • 00:16:20 retrieve that data I'm storing here
  • 00:16:22 in my custom error-handling logic so if
  • 00:16:25 I now reload and click post data we see
  • 00:16:28 that error data is all the part of the
  • 00:16:30 output so this is how we can use the
  • 00:16:32 fetch API generally it's nicer than xml
  • 00:16:36 httprequest has a nicer syntax I'd say
  • 00:16:38 but easier to use less clunky but
  • 00:16:41 browser support is worse which means you
  • 00:16:44 might need a polyfill and in addition
  • 00:16:46 this error handling logic can be
  • 00:16:49 annoying it's not that different from
  • 00:16:51 the error handling logic we have in xml
  • 00:16:54 httprequest but at least there we didn't
  • 00:16:57 have that extra response body parsing
  • 00:16:59 step we do have that here in the fetch
  • 00:17:02 API which means we have to find a
  • 00:17:04 solution like this inner wrapped promise
  • 00:17:07 chain nonetheless of course is up to you
  • 00:17:09 which one you prefer fetch at least uses
  • 00:17:12 promises natively which is a plus and
  • 00:17:15 might have some other syntax features
  • 00:17:16 which you like and therefore it is a bit
  • 00:17:18 more popular but definitely XML HTTP
  • 00:17:21 request is still also getting used a lot
  • 00:17:24 actually it's always getting used by the
  • 00:17:26 access package which is the package
  • 00:17:28 we'll have a look at in the last video
  • 00:17:31 of this mini series now with this video
  • 00:17:33 you hopefully have a basic understanding
  • 00:17:35 of how the fetch API works how it
  • 00:17:37 compares to XML HTTP requests and how
  • 00:17:40 you use it
  • 00:17:41 now let me also note that we just had a
  • 00:17:43 basic look at it of course there are
  • 00:17:45 more differences in in the detail when
  • 00:17:48 it comes to sending cookies to a
  • 00:17:50 backhand and stuff like that but
  • 00:17:51 generally you hopefully already have a
  • 00:17:54 good understanding of how it compares
  • 00:17:56 where it's better and where it's a bit
  • 00:17:58 more annoying to work with it now turns
  • 00:18:00 out we have another great option for
  • 00:18:02 working with HTTP requests and that's
  • 00:18:05 the Axios library that's what we'll have
  • 00:18:07 a look at in the last video of this
  • 00:18:09 miniseries