Jonas: Welcome to the first coding challenge
of this section
and also in a long time, actually.
And this one is gonna be a big one.
And so let's get started right away.
And in this challenge,
you're gonna build a function, where am I,
which then displays a country on the page,
but based only on the GPS coordinates
that you provide to the function.
All right?
So instead of providing a real country name like Portugal,
all you will provide is coordinates
of any place on the world.
And based on these coordinates,
then a country will be rendered
just like we have been doing.
All right?
And so for that, we are going to use a second API
to basically geocode coordinates.
And so here are your tasks.
So again, create a function, where am I,
which takes as inputs the latitude and longitude,
so coordinates, as you already know.
And as always, we have some test data down below.
Then the next step once you've got these coordinates is
to do reverse geocoding on these coordinates.
And reverse geocoding means to convert coordinates
to a meaningful location,
for example, a city or a country name.
And so the API that we're gonna use for that is this one.
Now, unfortunately,
shortly after recording this video,
this Geocode called XYZ API also stopped working.
And so instead of this one, please use the API URL
that I'm displaying here on the screen right now,
and which is also part of the starter files
to make it a bit easier for you.
All you need to do then with this URL is to replace the lat
and lng values with the correct latitude
and longitude values.
Now the result of this new API is pretty similar
to the old one, with the only change being that instead
of the country property, you will need to use country code.
But no worries, I will later also display that
on the screen when necessary.
And with this small but important new instruction
out of the way, let's get back to the challenge.
So to do this, you should use the fetch API, of course,
and then also promises just like we have been doing
in the last couple of videos.
However, do not use the get JSON function
that we created previously.
So that would be cheating
because it would make this whole challenge too easy.
Next, once you have the data, take a look at it,
and then using the data, print a message like this here
to the console.
Then chain a catch method to the end of the promise
and log any errors that might occur to the console.
Then finally, there's one important thing about this API,
which is that it only allows you
to make three requests per second.
So if you reload the page really fast,
then you will get an error with the code 403,
and this is an error with a request.
So it's a little bit like the 404 error
that we worked on before, remember?
So the fetch function does not reject the promise
in this case, and so you basically have to do that manually.
And so that is step five.
And so with that, you completed part one.
So part one is basically about reverse geocoding,
and then in part two, it's time to use the data
that you get from step number one to render a country.
And so take the relevant attribute from the geocoding API
and plug it into the country's API that we have been using.
And just like we have been doing, render the country
and also catch any errors.
And for this one, you can actually even copy the code.
So there's no need to type the same code,
at least if you are in a hurry.
So if you want to write the same code again, of course,
that's still great because that will help your muscle memory
to really internalize these concepts.
Now, if for any reason,
by the time you're watching this course,
this API here is no longer working,
then please just Google for another reverse geocoding API.
So I'm sure there should be another one
that you can use, okay?
But anyway, once you have all of this done,
then you should test your function
with these three test data coordinates.
So hopefully you can complete this challenge
and have some fun along the way.
So I designed this one to, one more time, be fun for you.
So go have some fun now,
and I'll see you back here once you're ready.
All right, so here I am back,
and here goes my solution.
So where am I is the function that we're gonna create
and that you hopefully created it yourself.
And so if your code works perfectly,
then there's actually not even a need
to watch this video probably to the end.
But anyway, let's now take this URL format
and then do a fetch request to this URL.
So fetch,
here, let's use a template string,
because now here we need to plug in the latitude,
and then here after the comma, we need the longitude.
All right?
Then on this, we call the then method.
And here we get the response.
Let's just call it res for now.
And then immediately we return res.json,
which, remember, will return a new promise,
and it is this one, which then will get the data
because the data is going to be the resolved value
of this promise.
And so let's just take a look at the data here.
So let's reload here.
Oh, and of course, I need to call this function indeed.
So let's grab these coordinates, give it a save.
And so now it actually already worked.
All right, so let's open it
and let's see what kind of stuff we have here.
So we have the city, we have the,
so basically the confidence that this data is correct,
which is 90%, which is pretty good.
So the country is Germany,
and then here we have all kinds of stuff.
But what matters is actually the country,
at least for part two, which is gonna be
to render the country,
but for now the task is to log to the console as string,
you are in city and then country.
So like in Berlin, Germany.
Now, okay, so let's do that.
So you are in,
and then data.city,
data.country.
Country, like this.
And all right, so we are in Berlin, Germany.
Let's actually already do this with the other coordinates.
So, let's see what countries we are in.
I actually have no idea.
All right, so we get undefined, undefined.
And so this is actually the problem
that I was mentioning right at the beginning.
So, this one,
where the API, sorry,
so where the API only allows three requests per second.
And so now we got this error, 403,
and so indeed it is exactly this one, all right?
And so one more time, the fetch function
is not correctly handling this error.
So it is not rejecting the promise
even though this clearly is an error.
And so, as you already know,
we need to now manually do that.
So here we need to now return.
And just to make sure, let's take a look at the response.
And this doesn't always happen, okay?
And so in this case, it actually worked just fine.
So one of these here is Cape Town, South Africa,
and the other one is Mumbai in India.
All right, so let's try to reload again very fast here.
And so now we get that error again.
Okay, so where is that response?
So the one that's associated to 13.381,
so that's this one.
And so one more time you get that OK is false.
So let's use that to our advantage.
So if res.ok is false,
then throw new error
with the error message, "Problem with geocoding."
And again, let's actually include
the status code here.
All right.
So here we are throwing a new error,
and so we are rejecting this promise
that's gonna be returned here,
but we are, as of now, not catching it anywhere.
And so at this point, we would have
an unhandled promise rejection,
and actually let me show that to you.
So I need to save this a bit faster
in order to create the error.
So, sometimes it's not that easy to catch it.
Let's do it really fast here,
now, all right.
So now you get uncaught promise, basically.
So the error message is already the one that we want,
but it should not be uncaught, right?
And so indeed we need to catch any promise rejection.
And so let's do that.
And all I'm gonna do in this case is simply log it
to the console as an error,
simply the error.message,
and then I will again like add an emoji here,
just so we know that it's our own message.
Now, okay,
something is missing here apparently.
So here again, we get problem with geocoding.
And so now we successfully handled the error
and could now do something more meaningful with it
if we had to, like again displaying some kind
of error message or logging this error
in some error-tracking application.
Now, okay, so I think with this,
we actually already completed part one.
So we did four and five in the opposite order,
but that's okay.
And so now it's time to use this data to render a country.
And so this is essentially what we already did before,
so I'm just gonna come here and copy that.
So let's see where that is.
Well, it's even more up there,
or actually it's not.
So actually, I will just copy this part here
of the error handling.
Oh, and actually I can get all of it.
Okay, so let's paste that here then.
Let's get rid of these comments.
And of course now here, we need to do a new fetch.
So return fetch,
and then, well, actually I need to go back
and get the country as well.
So yeah, that's essentially this URL here.
Okay.
So let's save it.
I'm not sure if it's gonna work yet.
And it doesn't.
And that's of course
because this country here doesn't exist.
So the country that we need is stored in data.country.
And so here we are now logging this string
just like we were doing before.
And then based on that country, we have our next fetch here,
which we will then return.
And then here we have that part
where we handle the error if the country cannot be found.
And finally here, then we render that country,
but it is not gonna be a neighbor.
So let's get rid of this part.
And up there, we called response simply res.
So let's do the same here.
And for now, let's test it only with one testing data.
So let's see.
And now we still get an error,
"Cannot read property, 0, of undefined."
So where does that come from?
And so this stack trace here is, once again,
not really helpful,
but I think that I still know the answer.
And that is because here we actually needed
to take the first element of the array,
if I remember correctly.
Well, now nothing happened.
Oh, but I think I know why.
And the reason for that is
that previously we had this finally here.
So we had this finally, which set the country's container
opacity back to one.
And as we did that, we removed this from here.
So right here.
So basically, now we should set this back here
so that we can be back to using it in the future.
And so if I save this now, oh beautiful.
There you have it.
And this is really amazing.
So just using the GPS coordinates,
we can now determine the country that we are in
and then also display it along with a bunch
of information about the country here on our page.
And all thanks to the power of APIs
and also asynchronous JavaScript.
So let's now also test with these two,
now, right?
But now here in one of them,
we actually got an error with geocoding.
And again, the reason for that is
that we can only do three requests a second,
and so sometimes this then doesn't really work.
Oh, but now we actually got all three.
Now this one here for India
looks a bit weird, right?
So this one is India,
but when we get the data for India, then apparently,
because this country also has India in its name,
this is then gonna be the first country
that is found, right?
So there's probably multiple countries for India,
but yeah, that doesn't really matter here in this case.
If you want, you can just use some other coordinates here.
All right?
But anyway, again, I hope you had some fun,
and this was a great use case
for how we can actually use multiple APIs in sequence
to create a really amazing result like this one.