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.