3.1 API calls from Node.js (Weather data from Dark Sky) - Working with Data and APIs in JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[BELL RINGS] Hello and welcome to module three of working with data and APIs in JavaScript. So I just wrapped up module 2, the second part, with a project called the Data Selfie App. And there were some new things hopefully to you that you learned and are excited to apply in future projects like server side programming and GET requests and POST requests and saving data to a database, all of the things. But I think there are some key elements of building a web application that involves data from external API and server side and client side that I missed. One of the most crucial things I think is making an API request to an external data source from the server, and there are a variety of reasons why you might want to do that or need to do that. And I really want to demonstrate that in this new project called The Weather Here. The original Weather Here project is once again by Joey Lee and was built for a course called Quantum Humanists at NYU, where I also teach. In Joey's project, the user arrives on a web page. There's information about latitude, longitude. We know how to do that already. There's information about the current weather and air quality. This will be new that we want to add and then a big Check In button. So a press Check In button, all that information is logged to a database, and then there's also a view where you can view all the different check ins plotted on a map with leaflet.js. Most of the functionality that I need for this Weather Here app we already have it from the data selfie app, but we can start with this baseline of code from there. But there are some new things that I want to demonstrate to you in this project. So number one is I want to add connected to external API. So we're going to use two different APIs-- one for weather information, one for air quality. One of those APIs going to require an API key and not actually even allow us to connect from the client side. So we're going to have to look at, well, how do I connect to an API from Node but then have the client build display that information? So that's going to be a key new thing. Now I also want to figure out how do I hide the API key. So if I want to open source and publish my code but I don't want include my API keys, how do I do that? So that's going to be an important piece of this as well. This project also allows us to kind of play with our logs page, and let's look at instead of just a list of all the information in the database, how do we pull a bunch of records from the database and plot them on a map? And mostly, we can pull from the previous example I made with the International Space Station to create a map with leaflet.js. And finally, before I go, before this series wraps up, I really think it's important to talk about deploying a project into the real world, so to speak. So right now, I'm tinkering and playing around, developing the service running here, the clients running here. This is just all contained within my laptop. But if I want to deploy this project to a server so that it can live on the web that many people could access that share of the data, participate in, and view the website, essentially. How do I do that? So we're going to look at a few different options for deploying your project onto the web. Hopefully, I'll give you some pointers. It is an option where you can do that for free as well as if you have a larger project, what sort of considerations are for our hosting services and paying for hosting. So this is where I'm going to begin. I've got just sort of the very basic functionality from the data selfie app. I stripped away p5, the webcam images, a lot of stuff. The page just loads and shows my latitude and longitude. When I click Check In, it's saving that current latitude longitude and the timestamp to the database. And when I go to View Check Ins, I see a login of all of my recent check ins at this latitude, longitude, and time. So the very first thing that I want to do in this series now is add weather. I want to build this display on this Page information about the current temperature outside at this latitude and longitude. Now I have to figure out where I can get the weather information from. So I don't really feel so inclined to build my own set of sensors in my own weather station. So most likely, I could find some type of APIs service that I can make a request to get the data back, maybe even in JSON format. This is very similar to what we did when we looked at the International Space Station latitude and longitude from an external API. And there are many weather APIs, Google Weather API, JSON data. You'll probably find a ton. One that I've used in previous video tutorials is Open Weather Map. That's one that you could look into using. The National Weather Service-- probably their other governmental organizations or public institutions that have public weather data that you could use that have APIs, and you request data from. I'm somewhat arbitrarily picking an API call Dark Sky. What are the things I look for when trying to pick an API is, does it have good documentation? Are the examples easy to follow? Can I get up and running with it fairly quickly? And looking at Dark Sky, I find that to be true the documentation is pretty easy to follow, and I can get up and running with it quickly. And it offers the data in JSON format. While it's not entirely a free service, it lets you do 1,000 API calls per day free, and that's for demonstration purposes. That's pretty much all I need. A risk here, of course, is that by the time you're watching this video, the Dark Sky API won't exist anymore or the way that it works will have completely changed. But that's just a fact. So really, what you should be taking away from this video is less the specifics of the Dark Sky API but what you need to do when you find an API, how to get your API key, how to make the request, how to get the data and then present the data, and hopefully, maybe follow along with this video along but use a completely different weather API while you're following. So unlike the International Space API that we looked at in a previous video, the Dark Sky API requires you to authenticate. It's pretty simple to authenticate. All you need is a single API key. Other APIs can have a much more involved process. But if you're going to follow along and use this, you're going to need to first go to darksky.net and click sign up. You're going to want to register with your email address and make up a password. Now I've already done that, so I'm just going to go straight to logging in. Once you're logged in, you're going to arrive exactly to this page. And you can see this is really important. This is my API key. It's a little bit of irony here that I've made this public video on YouTube showing you my API key right here. By the time you're watching this, I'm going to have regenerated my API key, and this one won't be valid. So don't try typing this one in. You're going to need to get your own. But while I'm making this video, this is one that I'm going to use. The other thing that I love about this-- already, I need to read the documentation. But even without reading the documentation, right here, I can see a URL for making an API call. So if I want to get the forecast all I need is api.darksky.net/forcast. That's the endpoint. We've learned about endpoints. Now my API key and then slash latitude comma longitude. So I can actually just click on this, open it in a new tab. And we can see, look, this is weather for that's a latitude and longitude for Los Angeles. I'm getting a summary. I'm getting near storm distance-- all sorts information. I can use any of this in my application. So let's assume what I want to do is now request this API endpoint in my client-side JavaScript. That's the thing that we've done before. We did that with International Space station. So I'm going to grab this URL. So right here, once I geolocated, then I can say I can make an API URL, which is equal to exactly that. I'm going to make this a string literal because instead of hard coding in the latitude, longitude, I might as well say latitude comma longitude. And then now I can say this is all stuff we've done before. I can fetch-- make a GET request to that API URL. So I can say the response equals await fetch API URL. Now since I'm using the keyword await, I need to add the async keyword up here to this callback function. Then I can say JSON equals equals await response.JSON. And then I can console log the data. So in theory, now, the feature that I've added here in addition to geolocating, I'm going to take that geolocation, set it to the darksky.net API, and get the weather information back. Let's try giving that a run-- going here to here, hitting refresh. I'm the only person in the entire world that's really excited to see the dreaded CORS error. CORS stands for Cross Origin Resource Sharing. It can be enabled or disabled. If it's enabled, it's saying like, hey, I want you as a separate server from a different origin if you'll share my resources. Now, the thing that's sort of crucial here. If, of course, it's disabled, it's not that the API is saying you can't have access to my data. It's just requiring that you do it from your own server. And this is one that's explained in the Dark Sky APIs FAQ. If you scroll down, you'll find the question, why do I get the error, no access control out origin? And it's because they explain that it's for security reasons. Because the API key is part of that request, they want you to enforce that you can't make that request from client side code. You can only do it from server side code. So this is a nice demonstration of how we're going to make that request from node itself. So in fact, what I want to do is take this code itself and put it in the server. So go to index.js, and I'm just going to paste it in the bottom. But where do I want to call this? I want to make a new endpoint in my server that receives the latitude and longitude then makes a call out to darksky.net and then returns that back so that I could actually have this still in my client. I don't want to actually remove this. What I want is to change this URL maybe to just a local path weather slash latitude longitude, weather being the endpoint that I'm going to create and then console log it here. So I'm going to go into the server. I'm going to make a new endpoint for a get request. I'll call that weather. This is now a function that gets closed off like this. And now, OK, I'm getting some errors here. What's the issue? This is a couple of things. One is the argument is to the function is called response, so I really should call that response here. So I'm just going to call this fetch response and then say fetch response.json. But there's a missing piece here, actually. Number one is this needs to be an async function because I'm using await. And then instead of console logging, I want to say response.json.json. So I'm going to make the API call from within here and then send it back. This is what's known as a proxy server. It's basically the server is a proxy for darksky.net. I can't make the call the darksky.net directly in the client. So I just send off the latitude, longitude, receive it here, and make that request. But wait a second-- how do I have these variables, latitude, longitude? Oh boy, this is opening up a can of worms about passing parameters with an API. Here I am in the client side code. I want to send to my new weather end pointthe latitude, longitude that I've gotten from the client side code. Then somehow in the server, I need to receive those and put them in here when I send the Dark Sky. Now I need to show you how this is going to work. But for right now, let's just make sure this is actually working. Let's just hardcode in the latitude, longitude. So I'm going to go back to this particular latitude, longitude that I know will work. I'm going to go to my server I'm going to comment this out, and I'm going to paste in a hardcoded latitude and longitude. So now when I go to that endpoint, I don't need to pass in a latitude and longitude. I am just going to get exactly the weather for Los Angeles. I'm also going to do the same thing in the client. I'm going to just temporarily comment this out and then get rid of the latitude and longitude. And I think for the paths to be correct, I should have included a slash here. OK, so let's restart the server. Let's go to the client and hit refresh. We didn't leave out an async function, sketch.js. I forgot to put my async function in here. Ah, right, let's check the server, of course. So up here, it's going to give me a nice error that says fetch is not defined. Fetch is not defined. I forgot about that. Fetch-- the web fetch API-- is part of the client side browser API. If I want to use it from within Node, I can, but I need to install a Node package for that. The package I can use to do that is called Node-Fetch. So I'm going to go over back here and say NPM install node-fetch. If I go to my package.json, I can just see that that's in there now. And then most likely, what I need to also do is say a const fetch equals require node-fetch, so that's going to pull the fetch function from node-fetch. So I can add that up here at the top, fetch equals require node-fetch, rerun the server, give it one more refresh here. And there we go-- look at that. I now have the weather from Los Angeles right over there. The last step here-- I know this has been a bit of a longer video than usual, but I just want to finish off this one last step-- and this last step is sending from the client the latitude and longitude to the server, so the server could send that latitude and longitude to Dark Sky, get the weather, and then send the weather backend to the client. The way that I'm going to do that is with route parameters. Now, we learned about routes. If I have a GET request or a POST request, I set up a route, a path, an endpoint for that particular request. Route parameters are extra parts of that path that you can name and capture as variables, essentially, with data that's sent from the client. Another way to do this is with something called a URL query string, which I cover in another video. And so either way would work here, but I'm going to go with route parameters. So here on the express documentation, we can see that a route parameter is specified with a colon. So the route is users. And then I might say users slash Daniel or users slash Schiffman, and that will come in as a user ID parameter. So to add that, I'm going to go back to the server. I can remove this hardcoded lat, long in and put back in the one that has the latitude and longitude variables. So now, I need to add the root parameters. So one thing I could do is I could do slash colon lat slash colon long, so I could have two parameters coming in. I don't know. I think I'm going to just make it one. I'll call it lat long. And then I'll send it in with a comma. And those, you can see I haven't used this request argument yet. This is finally a chance to use that request object. Inside of the request object is a property called params, and inside that params object are all of the parameters. In this case, there's just one parameter-- something called lat long. So I could type in lat long, or I could also put that I could also put that in brackets in quotes. So either way, this will work. I'm going to just go with the dot syntax. And what I'm going to do is I'm going to put that in another variable. So I'm going to say constant lat long equals that. And then actually what I'm going to do is undo is I'm going to do dot split, and I'll split with a comma. And then the latitude is the lat long index 0. And the longitude is lat long index 1. So in theory, as long as I send in as the route parameter the latitude and longitude separated by a comma, I can pull it out of request.params, split it by comma into an array, and put them in each one of these variables. So I probably should have done this more incrementally and console log some stuff. But let's just hope that this works. I'm going to add some console logs to debug just so I see in case something goes wrong. Then I'm going to go back to the client. Now I need to go back to the client code. And here I can go back to this because this is exactly what I'm sending in. I'm going to the weather route with the parameters latitude comma longitude. I already set that up. OK, let me add one more console log request.params, so we can see the raw request params. And let's hope that this works-- go back to the browser hit Refresh. And there we go. I have got the correct latitude, longitude, route and the weather now from New York, the actual latitude, longitude that I sent to the server. Let's check the servers logs and there you go. You can see, there we go. So this is the request parameters that came in. There was just one called lat long. Then I used split to turn it into an array, and then I took the 0 index of the array and index number one of the array. So luckily, I wrote the correct code, and it actually worked. The next step here would be to present that information-- well, there's several next steps here. I need to save stuff in the database and all sorts of other things, but the small immediate next step would be to display the weather information here in the DOM itself. So I'm going to leave that for you as an exercise. I will do that at the beginning of the next video. And then I'm going to continue on and make a request to Open Air Quality, the Open AQ API to get both the weather information and the air quality information for a single latitude and longitude. [MUSIC PLAYING]
Info
Channel: The Coding Train
Views: 96,329
Rating: 4.942215 out of 5
Keywords: API, weather data, weather here, dark sky, external api, node.js, javascript, coding, coding lessons, coding challenges, nyu itp, nyu, dan shiffman, web development, weather api, node.js web application, node.js express, node.js tutorial, node.js tutorial for beginners, javascript for beginners, javascript functions
Id: ZtLVbJk7KcM
Channel Id: undefined
Length: 17min 49sec (1069 seconds)
Published: Wed Jun 12 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.