Here I am in San Francisco, at this latitude and longitude,
with a temperature of around 54 degrees
Fahrenheit and some particulate matter in the air.
That was last recorded just yesterday.
Oh, excellent.
So this is a pretty recent air quality rating.
So this is where The Weather Here project is right now.
And what I want to do in this video is now,
every time I press this Check In button,
save all of this information into a database
so that I could go onto a View Checkins page--
there's nothing there right now--
and see all of the records, everything
that I've ever saved in the database, plotted on a map.
I'm realizing, however, that this button that I have here
is kind of useless.
I have this Check In link and the View Checkins page,
so every time I go back to check in,
it's reloading my current latitude and longitude
and checking me in.
I could have that happen in a separate button.
This is really an interaction design question.
So I'm not going to pretend to get into good user experience
or interaction design in this video.
I just want the functionality to work.
So I think to simplify, I'm going
to get rid of this button, and just have--
whenever the page loads--
have the information logged into the database itself.
And then if I want to relog in to the database,
I can always just click this Check In link, which
will then refresh the page.
And this is going to simplify a lot of things.
So I'm going to move and remove this button.
So if I go back here, we can see--
OK the button is gone.
Now I have this addEventListener missing.
So I can go back to my code.
And ultimately, all of this stuff
that's happening right here, when I click the button,
is POSTing to the database.
And what I want to do?
I want that to happen right here.
So I want to send everything to the database
right here, after I've finished all of my API calls.
And I can paste that in right here.
And what I actually want to put in the database
is the latitude, the longitude, the weather,
and the air quality.
So this now would take all of that data,
and send it back to the server, and save it into the database.
This is functionality that we already
built in the previous Data Selfie App project.
There is a little bit of an irony here, I suppose.
I request the data from Dark Sky and OpenAQ on the server,
send it to the client to display on the web page,
and then send it back to the server
to put it in the database.
I probably could bypass that and actually just
have it go into the database itself--
right here, when I'm actually requesting that weather
information at that latitude and longitude.
But I really wanted to keep things modular and organized
and have a completely separate route--
this POST route that puts stuff into the database.
This is arguably a better way at least
to demonstrate how to do this in larger, more scalable projects,
even though it doesn't really matter here that much.
So going back into sketch.js, I can see I'm now--
have this thing entering the database.
And what I'm going to do is I'm going to refresh this page.
Response has already been declared.
So once again, I'm kind of using the sequence of API, URL,
response, JSON.
And I've got that down here--
response, JSON.
So let's call this db_response, db_json.
And we'll put this here.
And then, just to see that, let's
console.log the db_json to see that it went into the database.
And here we go.
Hit refresh.
OK, so this is what was saved in the database-- all the data--
and it's displayed here.
I can go to View Checkins and we can see-- there it is.
There's nothing on the web page here.
It's just console.log-ing what's in the database.
And I can go back to check in again, and check in again,
and I can switch my location to Moscow, and check in again,
and check in again, and switch my location back to Berlin,
and check in again.
And now, if I go to View Checkins,
we will see there are six entries into the database
at all these different latitudes and longitudes
with this weather and air quality.
And if I go look at my actual database file,
I can see everything is here in the database file, as well.
One quick thing before I start to look
at plotting the checkins themselves
is, you'll notice that the default from Dark Sky
is to get the temperature reading back in Fahrenheit.
This can be changed.
If I actually look at the API documentation,
there's a little section on units here.
I can add a URL query string property,
units equals something, to specify the units.
And SI units-- or international system units,
which is typically Kelvin--
but that would come back--
SI units would come back in Celsius.
So I could go to the server where
I'm making my request to Dark Sky,
I could add a slash and then a question mark for a URL query
string, and then say units equals SI.
And then, of course, I would want
to update my index.html page, accordingly,
which is right over here.
And change that to a C. And then go back and hit Refresh.
And there we go.
I've got Celsius.
So I just wanted to make sure I showed that to you before we
go on to the next step of plotting everything
from the database.
Moving on to View Checkins, what I'm going to go do first is
just grab my code-- my Leaflet.js example code--
from the International Space Station
project so that I can start with a map on this page.
[MUSIC PLAYING]
I'm back, and I've added a map to the page using Leaflet.js.
So the only things I pulled from my International Space station
examples are the URLs for the leaflet.css and leaflet.js
files, and then a div for the checkin map--
I'm calling it checkinMap-- and then in logs.js, I just
have a little bit of code to specify the tiles
from OpenStreetMap and place the map at with a zoom level
one, latitude longitude zero, zero, right there on the page.
The data from the database has been
loaded with the getData function by making a fetch call
to the API endpoint.
And we can see here in the browser,
these are seven checkins at seven different latitudes
and longitudes, along with the weather
and, presumably, also the associated air
quality information.
So now, what I want to do on this checkins page
is see all those points on the map.
Now, while it might be fun to draw some kind of path
from checkin to checkin or some kind of custom drawing
on top of the map, I'm just going
to do, for simplicity's sake, the same thing I
did in the International Space Station example,
and place each checkin as a marker on the map.
So if I go to the Leaflet documentation,
I can grab this marker code, go back to my code.
And here is the for loop where I'm
going through every element from the database.
So I've gotten the data from the database and I
can set a marker to data dot--
oh, item, sorry.
It's item dot latitude comma item
dot longitude, and add it to--
what did I just call it?-- mymap.
So there we go.
Now, if I go back to the page here, we see-- there we go.
I've got a marker at every one of my checkins,
and I can zoom and find it.
Now, if I click on the checkin or if I hover over the checkin,
nothing happens.
So the only last thing that I want to do
is place some text over the checkin that has the weather
and air quality information.
I've basically done this already,
so I'm just going to repurpose the code that I had before.
I'm going to switch over and find that index.html page which
has this text.
I'm going to grab it all.
I'm going to bring it over here to my logs file,
and I'm going to say const text--
So I'll just call it txt--
equals-- and I'm going to use a string literal.
And now, these were all spans, but what I'm going to do
is just pull the data that I want.
So here, I want to have item dot latitude, item dot longitude,
and then now, I just want weather dot summary.
And I'm going to finish this off.
[MUSIC PLAYING]
All right.
I have now typed all of this in.
I've got a long block of text-- a narrative, so to speak.
With my text, the weather here is,
and then I'm pulling bits of data
from each element of the array of information
I got from the database.
So for each item in the data array,
I get the item's latitude, the item's longitude, the item's
whether summary, the item's whether temperature-- all
this stuff.
This is the way that I've organized it.
And then what I should be doing is saying, take that marker,
put it in a variable, and then say, marker bindPopup.
This is a function that's part of Leaflet.js where
I can bind some text to a popup any time I hover
or click on a marker.
Bind that text.
We can go see, now, if this works.
Go over the browser.
Hit Refresh.
And there we go.
We see all of the markers for all of my checkins.
And if I click on any of them, look, there we go.
I've got the information about the weather and air quality
at that time of checkin.
All right, let's add one more checkin.
So I'm spoofing this location, which is Rainbow street,
in Jordan.
And I'm going to hit Check In.
And then-- oh, no, there's no measurements there.
So I would like to still put the checkin in the database,
even with no reading, and then have
that be a pop up that just says, no air quality reading.
I just really-- I want Rainbow street in my database.
So right now, I don't think--
I think if I go back to my code, we'll
see, here, that if the error happens and there's
no reading available, I don't add to the database.
So let's think about how to handle this.
I am going to make these variables--
let lat, long, weather, and air all
be variables before the try.
Then I'm going to set lat, long, whether, and air.
And then I'll take this, where I POST it to the database,
and I will have that happen after the try catch.
So no matter what, the air will be entered into the database.
But if there is no reading, what I'm
going to do is I'm going to say, air equals an object
with value of negative 1.
So I'm going to hard code something into the database,
if there is no reading, with this value of negative 1.
And that will get POSTed into the database.
So now, I could go back to my checkin.
I'm going to check in again on Rainbow street
in Amman, Jordan.
That got entered into the database.
Now I can go to the View Checkins,
but I've got to check now--
I've got to go to my logs code and if item dot air
dot value is less than zero--
so it gets a negative reading--
I want my text to be different.
So we're going to start with the weather information.
Everything's going to have weather information.
Then I'm going to say, if it's negative I'm going to do txt
plus equal " No air quality reading.", with a space.
Otherwise, I'm going to add the particulate information
with a string literal.
And this should come up here.
OK, I'm good.
So this is a little bit convoluted,
and maybe there's a nice way to make this more elegant.
But I'm creating the marker, I'm putting the weather text in.
If the what comes back from the database
is a negative 1 for the air value,
that means there's no air quality reading.
Otherwise, I put the actual air quality reading in the text.
So let's see now, if we view the checkins,
if we have Rainbow street in Amman, Jordan with no air
quality reading.
View Checkins-- oh assignment to const variable.
Oh, so this can't be a cont.
It's got to be let because I'm adjusting it.
Let's hit Refresh.
View Checkins.
And there-- look, this looks like--
no air quality reading for Amman, Jordan, right there.
This project is completed, sort of.
There's a lot more that you could do.
First of all, I haven't really taken the time
to think about visual design or interaction design.
You might take a look, once again,
at Joey Lee's version of the project that
has a lot more design elements to it.
You might think about, well, how is the map?
Where's the zoom happening?
There are so many different ways you could draw on the map.
Maybe you can have a path between checkins.
Think about animating.
You can rewrite the text to have more poetic language.
There are a lot of possibilities.
You could even just-- there's a lot more data
in there from the weather and air quality API than I'm using.
So I'm going to let you take this project further
in those directions, but I want to show two really important
things in two separate videos.
Number one is, if I went to open source this, which I do,
how can I open source this and publish the code without my API
key?
Without just sort of having to delete my API key?
What is a way to deploy a project, separating out
secret keys that you want to be hidden,
separate from the source code?
So I'm going to show you how to do that with something
called an environment variable.
That will come in the next video.
And then the last piece that I'm going
to show you, in the final video, is
had actually take this project and deploy it onto the web.
So I'm going to look at, maybe, a few different options
for doing that, and just pick one
that you can follow along and have your project live online.
So thanks so much, and see you in the next video.
[BELL RINGS]
[MUSIC PLAYING]