Narrator: Welcome back.
And this is a very exciting lecture
because now you're finally going to use all the skills
you learned about asynchronous JavaScript
in order to make an AJAX call to request some weather data
from a real weather API.
And in order to do this we're going to use a modern
web API called Fetch.
And by web API I mean these parts
that are available to us in the browser but are not
really part of the JavaScript language itself.
Remember that from the event loop lecture?
Anyway, with Fetch we can do AJAX in a very simple way.
So we can do asynchronous network requests across the
internet to fetch data from other servers,
or even from our own server.
Okay.
So that's just what we talked about
in our last lecture, right?
Now we used to do this in JavaScript using
the rather complex XML HttpRequest interface.
And maybe you have heard of that.
It has actually better
browser support than Fetch because it has been around for
a long time now.
But I'm still going to use Fetch right now
here in this lecture, which is more modern
and it should work more than fine for us here.
And so let's test it out now.
So I'm going to get rid of this code here first,
just like before.
Okay.
So all we have to do is really to
use the fetch function.
So just like this.
Now in here we need to pass the URL
where the API is located.
So basically the URL to which we are sending the request.
Now we are using a weather API called MetaWeather.
So now let's talk a bit about that one.
I already have it here open, so it's on metaweather.com/api
and this page here is basically a simple documentation
of this API.
So normally APIs request a key in order to use it,
but this one is a very simple one and it doesn't require
an API key and so that's why I chose this very simple
MetaWeather API.
Okay.
So down here we have the
documentation and we can see here that there are three
methods in this API.
So the first one here is to search
for locations.
Basically you put in the name of a city
or something and it then comes back with a result which
contains these fields here in the response.
So the title of the location, the type, the latitude
and longitude, this ID here which means Where On Earth ID,
and then this distance here.
Okay.
Now this is not the one
that we want to use, but we want to use this location
method here.
This is basically to get the weather data
from a certain Where On Earth ID.
So this ID here
corresponds to a place on Earth.
So this is the API method, or the API endpoint,
which we can also call it, that we are interested in.
Down here we have some examples
and so let's check it out this one here for San Francisco,
which is actually the one we are going to use.
Let's open in a new tab and then you see this response.
Now maybe for you it looks like this in the browser,
so probably this is what you see.
But I have this very
handy Chrome extension installed which is called
JSON Viewer.
It makes it nicely formatted and more easy
to read, just like this.
So you see here, this is the URL of the API call,
so metaweather.com/API/location which is the endpoint,
so which is the method that we are using, and then
we also pass in the Where On Earth ID,
which is this number here, right?
So just following the format that we have here
in this documentation, okay?
So what we get back then is this object here, which is
not really an object but it's called JSON.
And so JSON
is a text-based data format which is very similar to
JavaScript objects, but the difference is that JSON
is really just a single string and not an entire
object inside the JavaScript engine.
This is like a string that we can receive from the server
and we can then easily convert it to a JavaScript object.
I'm going to show you how that works just in a second
when we start using this API.
For now let's just take a look at the result here and
what we have is the first field is the consolidated weather
and so we get an array of the weather on different days.
The first one is for March 15, and you see the minimum
temperature, max, wind speed, wind direction, air pressure
and all the good stuff like that.
Then we have the same for March 16, 17, 18, and 19,
and even 20. So I think it's a forecast
for five days that we get.
Then besides that array we also have the current time,
the sunrise, sunset, time zone, and all of this data here.
So we can get all of this just by calling the API on this
location endpoint with this ID here.
So basically with
this parameter.
This works kind of a parameter that we
pass into the API, simply by using it in the URL that
we called.
So let's actually use this one here.
All we need
to do is to pass this one into the fetch as a string.
And here we go.
That's it.
It looks a bit weird because it moved
to a new line here.
Ideally it would be on one line looking like this,
okay but we have no space for that,
so that's just how it looks.
Now just to test what happens here let's take a look at it.
Okay.
So now we get this weird error here saying
no access control allow origin header is present on
the requested resource.
So what is this strange error?
Well, the reason for this is the so-called same origin
policy in JavaScript, which basically prevents us from
making AJAX requests to a domain different than our own
domain.
So right now we don't really have any domain here,
we're just opening the JavaScript file.
And the domain
we are requesting this resource from is of course
the MetaWeather API.
And so because of this same origin
policy we cannot access this resource.
Now in order to actually allow developers
to make requests to different domains,
something called Cross Origin Resource Sharing,
or CORS, was developed.
I don't want to bore you with all the details here
but in simple terms, the developers of the API that
we are requesting from, they need to implement CORS
on their server.
That's actually the case for many
APIs but unfortunately not for MetaWeather.
So this is kind of a problem but we can actually still
fortunately solve this.
So what developers usually do
is to proxy or to channel the request through
their own server.
Like doing AJAX requests on our own server
where the same origin policy doesn't exist
and then send the data to the browser.
So this is just a work-around to that problem.
But of course we're not going to do that here because
we don't have our own server in this example, and of course
we want to keep it simple.
But we can still use a service
that does exactly that for us.
We're going to use a proxy
called crossorigin.me.
Let me actually show it to you.
That's misspelled.
So crossorigin.me.
And so here it says what it does.
A CORS proxy is a service that allows developers to access
resources from other websites, without having to own
that website.
And it's actually very easy to use.
All we have to do
is to prefix our own request URL with this crossorigin.me.
So let's test this and put it here,
and that should actually be enough already.
Let's reload it.
And now we don't get any error, but we also don't get
any result, right?
And that's because we didn't yet
handle the result of this fetch function.
So we simply fired off the request but then that's really
all we did.
We didn't handle any responses
or anything like that.
So let's now take care of that.
Okay.
What you need to know is that the Fetch API
gets our data and returns a promise.
And this promise
can of course return the data we want, or an error
if it couldn't somehow find the data that we requested.
So now we can use the then and catch methods on this promise
just like I showed you in the last lectures.
So remember how I mentioned that most of the time we
actually just consume promises and do not really
produce them?
And this is a great example of that.
Fetch here automatically returns a promise
without us having to write a promise ourselves.
So we are just consuming it here.
Now let's use the then method on it,
and also the catch.
Our callback function here has one argument and that is
the resolve value of the promise.
Remember that?
Let's just call it something like result.
This means that the data that comes back from this
fetch AJAX request will be called result here in this
callback function.
And so let's simply log it to the console.
Console dot log the result.
And let's also add the callback here for the
case that there was an error.
Let's just log it to the console also.
Let's see how that works.
And alright!
So now you see this response object here.
It has all of these fields here but what really matters
to us is this body field.
What you see now here is that
that is a readable stream.
That's a bit weird.
What this means that we have to first process this response
here with JSON so that we can then get the actual result
that we are looking for.
So the body here is where the
actual result is stored, but it's now as the readable
stream.
We actually have to convert it from JSON to
JavaScript just like I mentioned before.
How we do that?
Well, it's actually very easy.
We just use the JSON
method on this result.
And this JSON method, it also
actually returns a promise.
So we have to handle the
result of that and so again, we use the then method.
And we also chain it like we did in the lecture before.
Remember that?
Just like before we can return a promise
here and then add a new then method right after this.
So chaining, or asynchronous operations here,
one after the other.
Let's return
result
dot JSON.
So this here will return
a promise because this actually happens asynchronously,
this conversion to JSON, because it can take some time,
so therefore it happens asynchronously in the background.
As soon as it's ready it then comes back with the data.
So we need to handle that and so we add a new then method.
So let's call this one data now,
and let's simply log it to the console once more.
Let's fire it off.
And here we go.
There is our JavaScript object now containing
the data that we were looking for.
Great, right?
So we just did our very first AJAX call using
fetch and promises.
If you now take a look at this, this would be the exact
data that we had here in this example.
So you have the weather data here, which is an array.
So consolidated weather, then this array with all these
days, and then the remaining data that we have here.
And you see that this is still San Francisco.
So all that we need is actually right here.
Now to make this a bit more fun, let's actually log
something more exciting to the console than
just this entire object, okay?
We don't want to log all of this to the console but instead
let's just get this weather here for the first day
and then log some strings to the console
telling how the weather is today.
So count today
is data because that's this entire object here.
Then we have consolidated weather.
Let's just copy this one from here.
Remember that this is the array, and then today is
of course the first one.
So, number zero.
So that is today,
and let's log to the console
some kind of string.
We are using template strings here.
Temperatures in, let's add the name of the city.
You see this one is stored in this title.
So we have data
dot title
stay between, so let's just use the max temperature
and the min temperature.
So it is min and max.
Let's just write it out, that's easier.
So we have today dot min temp
and today dot max temp.
Alright.
Let's check it out.
It takes some
time to get the data, and then temperatures in San
Francisco stay between 7.52 and 11.36 degrees Celsius.
So this probably is in the degrees Celsius here,
which is what we use outside the US as you probably know.
So, great.
Let's just put this maybe in a function.
Let's just say function
getWeather and then we pass on the
Where On Earth ID into it,
to make this a bit more reusable.
getWeather, then we use this one here, as our ID.
So in here we just want this ID.
So let's use a template string here.
Oops, that's not, yep.
Alright.
So let's take a look at the example.
So another one here is London.
So the ID here is this one.
And so let's just call
it now for London as well.
So getWeather.
And so let's test it out now.
And it's okay.
So San Francisco is the first one and
the second one is London.
So it's working just fine.
Now let's just see what happens if we put some weird
number here that doesn't really return any result.
So something like this, which is probably not a valid ID,
so let's see.
And so what we get here first
is a 404 so basically this means it didn't find anything.
So that's and error coming right from line 98
so right from this fetch function here.
But then we also get this error here,
which is the type error cannot read property zero of
undefined.
And so that one comes from line 108 and so
that means that somewhere here in this chain
there was an error.
And so we can now add more logic here
in this catch method to actually handle that error properly.
But this was just to show you an example.
What we really want is of course,
for this to work just fine.
And that's it.
That's a very simple AJAX call using fetch
and promises using then and the catch methods.
I hope that made sense to you.
How we use fetch, how we
handle the result and how we convert it to JSON which
returns this new promise.
Then down here we simply
analyzed the response, and based on that we then simply
printed the pieces of data to the console
that we are interested in here.
So this is how you do it with then and catch method
to handle this promise.
But in the next lecture
I'm going to show you how we can use
async / await again to handle the data that comes back
from the server.
So once again you will see that it is
actually much easier and nicer to use also.
So stay tuned for that next lecture.