Hello, and welcome to
the first tutorial video in this new series, working with
data and APIs in JavaScript. So in this first video, I just
want to look at one thing, the web fetch API. Fetch is a function. It's a wonderful function. It allows you to fetch
stuff-- data, images, from all sorts of
different kinds of places and do stuff with it. So we're going to start
with a very basic example. It's right here. It fetches a rainbow image,
a local file, a JPEG file, and displays it on
the web page itself. That's going to build-- that's
the foundation on top of which we will build
other examples that are grabbing a
spreadsheet of data and graphing it, or reaching out
to some like Weather Service, and getting the local--
the temperature, based on the latitude and longitude. All sorts of
possibilities, we're going to start just
by looking at fetch. The best place for you to
learn all of the details with everything you
could ever possibly want to know about the fetch web
APIs is on the Mozilla Developer Network site. So that's where
I tend to look up documentation stuff
for JavaScript stuff I want to do in the browser. I'm going to show you
a small slice of what's possible with Fetch and kind of
build on that as we go video, video to video. There's this idea
in web programming of making a request, an HTTP
request, a hypertext transfer protocol request. I could make a get request. Will you please-- could I
please get some information. I can make a POST request. Could I please send
some information to you? And we're going to do both
of those kinds of requests. And fetch can actually
both retrieve and send. But in this example, I just
want to look at a simple get request with Fetch. Let me outline
these steps for you. So that our program
is going to do-- the first thing it's
going to do is going to call the fetch function. And it's going to give it
a single argument, which is the path to the resource. And in this case, it's
going to be a file. And that file is just going
to be a local file called rainbow.jpeg. The next thing we need to do
is deal with the response. So when we call fetch,
a response comes back, presumably with the data we're
looking for somewhere in there. I mean, it could be an error
or other things could come back as part of that response. But I'm just going to
write down response. Now this involves this
idea of a promise. And the fetch
function is a function that happens asynchronously,
meaning we call fetch, but some time passes
because it takes some time to retrieve that data. So how we get the response
as part of a promise is a detail that
I'm going to have to look at specifically
when we get into the code. And I will also include
in its video's description some links to further
details about how to work with JavaScript
promises, some other videos that I've made that might
fill in some of the gaps here. The response is actually
a stream of data. So we get the response but
we need a whole other step because we need
to read that data. We need to sort of
like complete that data and store it in a format
that we can work with. And the kinds of
formats we might have is like-- oh, it's text data. Or it's a blob. Maybe it's like image data
would come in as a blob. There's all sorts of--
there's array buffer. And a really, really
important one is JSON. So JSON stands for
JavaScript Object Notation. And this is going to be
a format for storing data that we're going to see
again and again and again. But in this case, we
want to get it as a blob. So I think we could call this
third step like complete data stream. And what I think
complete data stream-- I really mean complete
and grab the data that's in the body of the response. So there's this concept
of the response body which is pretty important, which
is where the data actually is. But it should be
noted that there's lots of other metadata about
the network communication that's in the response as
well, that you could look at in certain circumstances. So once we've done that, we've
completed the data stream. We've got the image blob. And then we can just-- this is really the
steps for using fetch. But in this
particular scenario, I want to make an image element. Make an IMG HTML Dom element. Make an image element
with that data. OK, so these are the
steps of this example. And I think we can
just go code this now. So what I'm beginning
with is just some boilerplate HTML basic
HTML file with nothing in it. And so let's add
some stuff to it. So first, let me add an
image element to the body. And I'm going to leave the
source of the image element blank. But I'm going to give it an ID. And I'm going to
call that rainbow. The next thing I
want to do is just add a script tag so I can put
some JavaScript with presumably that fetch function. Now ultimately, I might
want to put my JavaScript code in a separate file. I might want have a whole
build system for my project. But we're just working
with the basic ideas here. So I'm going to
just do everything in one file, one
HTML file that has the HTML stuff and the
JavaScript stuff in a script tag. And I'm going to say fetch. And I'm going to
fetch rainbow.jpeg. I'm going to put
that in the code and I'm also going to add a
console.log about to fetch a rainbow, because why not. So I'm using something
called live server-- it's a node package-- to host this particular
email page on my computer. So every time that I hit Save,
it updates in the browser. And you can see that now I
have that console.log there. Now I said earlier
that the fetch function returns a promise. And a promise is a
way in JavaScript to handle an asynchronous event. It gets resolved when
the event is over, when the data is retrieved. And I will refer you
to some other videos on my channel that go into
promises in more depth. But the quick explanation
here is that you can use the method then. So the method then
is a place where I can handle this response. So right now, what you're seeing
is I type the method then-- I put an argument response-- I use the JavaScript function
arrow syntax to then do something with that response. And what I want to do with
that response honestly, is convert it to a blob. But before I do that, let me
just say console.log response just so I can see it. So it helps to spell
things correctly. Response. And we can see
there's that response. And you can see all the metadata
associated with the response is here in the JavaScript console. And what I actually want to
do is say return response.blob because I wan to-- this is
what we talked about before-- I want to convert the
response into an image blob. That triggers another promise. So when I have
another promise, I can change them by
saying.then again. And now the response. If we look at that response--
console.log response, now I have the response
to the next promise. And we can see that is also not
defined because I cannot spell to save my life. That is now the blob. So in this case
actually, maybe it makes more sense for me to name
this variable something else, like let me just call it blob. And now, what you'll
see is there's this sequence is as follows. First, fetch the rainbow. Second, look at the
resolved promise and then convert that complete
reading the stream of data into a blob. So presumably, once I'm
there, all I have to do is say, remember I have
this image element. I have this image Dom element
with an ID of rainbow. I can say document.get
element by ID. Give it the ID rainbow and at
dot source, equals that blob. So this is me just taking
the data of that image which comes in as a blob,
and placing it into the source attribute
of the image Dom element. You can see that doesn't
work because the blob-- the data blob
isn't in the format that the image Dom
element expects. Luckily for us, there happens
to be a function called create object url that
takes a blob object and turns it into the
format that an image Dom element would expect. You can look up more
about this function also on the MDN JavaScript docs. But all I need to do here
is say url.create object url, pass in the blob. And there it is. We have our rainbow. It's kind of a large image. So I'm just going to
add another attribute, like with equals 480. So it sort of makes
the image smaller. And there we go. Oh, we have a beautiful rainbow. So this really wraps up
this particular tutorial. We've got the whole thing. We now know how to call fetch,
how to read the response when the promise resolves, how to
turn the data of that response into an image blob, and
add it into an image ELT. But here's the thing. There's a couple
other things that I've missed that it would be nice
to include in this video. Number one is I've done
nothing to handle errors. So what if something goes wrong? I should handle error, at least
log the error to the console so I can see that
something went wrong. Number two is I want to
introduce the JavaScript keywords async and await. And these are new features
of the JavaScript language that allow us to handle
promises in a slightly more readable and elegant way. So I'm going to show you. I'm going to rewrite this
particular example using async and await instead of
the dot then method. And I will also refer
you to some other videos I've made that go into these
keywords with a bit more depth. Let's first add
some error handling. One of the nice
things about working with chaining promises-- that
we have fetch, then this, then this, then this-- is that
error can happen anywhere throughout there. And I don't have to handle
each error in a specific way with each part of that sequence. I can just put at the
very end dot catch. So like a dot
then, which handles the resolution of the
promise, dot catch handles stuff that goes wrong-- when stuff goes wrong
during that promise. So I can write catch. I can give an argument error. And I can just say something
like console.error error. So this is a bit
more long-winded than it needs to be. There are ways of
condensing this. But in a moment, I'm going to
do that all with just async and await. So I'm not going to
worry about it too much. I'm going to make an error
happen just so we can see it. To be sure that this is
really happening though, let me put another
console log here like this will be my
own message-- just error exclamation point. And then what I'll do is-- let me misspell the name of
the ID of the Dom element. I will write rainbow
with two O's. And then, now if I go
back to the browser, you're going to see my
message error printed out. And also you can see the
actual error messages there. So this is a really nice
way of handling errors. One more thing. Let's look at how I
can condense the code and make it a bit more
readable using async and await. The way this works is if I'm
going to use this new keyword await, I can only
use the keyword await in the context of
an async function. Async is a keyword that
specifies this function is going to happen asynchronously. So essentially what I want to
do is write a new function. I'm going to call it async. I'm going to call
it catch rainbow. Oh, and I've got to
declare it as a function. So I could use the keyword
function or the arrow syntax. I'm kind of using them
interchangeably here. But I'm going to make an async
function called catch rainbow. Now when I call fetch, instead
of having to use dot then, I can still say
fetch rainbow.jpeg. I can set the result
of the fetch function to a variable called response. So this is like the dream
of how I like to write code. I just want to say the
response equals the result of the fetch function. But this is where the
await key word comes in. Because fetch is an asynchronous
function, I have to add await. So this is really
just syntactic sugar. It's the same exact thing that
I was doing with dot then. But because I'm in
a sync function, I'm allowed to write the
code in a single line by saying await
the result of fetch and store that result in this
variable called response. And then I can do the
same thing with the blob. I can const blob equals
await response.blob. And so now in two lines
of code, I've said fetch. I've gotten a response. I've said dot blob. I've gotten the blob. And then this other line
that I have down here, which puts the blob as a url
into the Dom element, I can just take that
and put that up there. And you see like all of that--
all those lines of code of dot then, dot then, dot then-- I'm going to keep
this catch by the way, because I'm going to
need this for something I'll show you in a second-- all of this gets to go away. Now look at that. It's just three lines of code. And I'll have to do now
is say catch rainbow. Just call that function. So I put all the stuff
that's asynchronous inside a function
that's async and then just call that function. And now if we go
over here, look! It's still working. There's our rainbow. But the reason why
I kept that is I do want to keep this catch thing
because if there is an error-- let me once again misspell
that name of the Dom element, we can see I have got- I
have now handled that error. I can attach the error
to the async function that I've written. And in fact, that
function by definition-- an async function by
definition returns a promise. So I could also say dot then. And you know, if I
wanted to do something to indicate that it's done,
I can say like, for example, console log yay. And now whoops, oh, I've got
to spell rainbow correctly. And there we go. We can see console log yay. So now I have the whole thing. I have written an async function
that makes the fetch request. It turns the body of what
comes back in the HTTP response into a blob. It converts that
blob into the format that the Dom element expects. And I've put a little
message saying, yay. It worked or an error
if there's an error. And that's it. That's this full example. Now that we know how to use
fetch in the generic sense when we're working with an
image here, in the next video, I'm going to use
fetch with a data set. I'm going to grab a comma
separated value file, a CSV file. This is a file from NASA. It's global world temperatures
from 1880 to present. And I'm sure you
had a graph those. But before we get there, I might
give you a little exercise. You could just move
on to the next video to see actually
working with the data and how you might
chart-- data file and how you might chart that. But as a little exercise,
you might try some things. For example, could you
fetch more than one image? How would you-- what if
you had an array of images? What if your file
was not an image file but maybe it was just
a plain text file? Could you put the text that
was in that file in a paragraph element? So try one or two
of those exercises. I will also include in the
GitHub repository that's associated with
this video series-- I'll include solutions
to those two exercises. So try multiple images. Try a text file and see
if you can get those to appear in your web page. So thanks for watching
this tutorial. And I'll see you
in the next video.