Using Fetch requests with api.weather.gov
Tags: javascript, webdev, beginners, programming
Published: 2023-03-06 05:26:49

An easy beginning project might include fetch requests to an API. I recently worked with some fellow students to create a mock weather app, and to get the weather data we decided to use Weather.gov's free API. 

Weather.gov's api, located at api.weather.gov, uses a gridpoint system to give you weather data at a specified point. In order to get their proprietary gridpoint data for a location, however, you must first fetch to '/points/{latitude, longitude}' with the latitude and longitude of that point. An important detail here is that the API will return an error if your latitude or longitude have more than 4 decimal places. This first fetch will return a few different API urls with the correct gridpoint location already inputted for you, where applicable. 

An example from the project:

```
function getPoints(location) {
    let correctedLocation = correctInput(location);
    let url = `https://api.weather.gov/points/${correctedLocation}`;
    fetch(url)
        .then(res => {
            console.log(res.status);
            return res.json();
        })
```
where 'correctInput' is

```
    let temp = input.split(',');
    let x = (parseFloat(temp[0]).toFixed(4)).toString();
    let y = (parseFloat(temp[1]).toFixed(4)).toString();
    return (x + ',' + y);
```
Luckily toFixed() already will take out any spaces in the original inputted string, so we don't have to worry about that. 

From here we should get an output with some key features
.properties:
> fireWeatherZone : "https://api.weather.gov/zones/fire/WAZ654"
forecast : "https://api.weather.gov/gridpoints/SEW/124,67/forecast"
forecastGridData : "https://api.weather.gov/gridpoints/SEW/124,67"
forecastHourly : "https://api.weather.gov/gridpoints/SEW/124,67/forecast/hourly"
forecastOffice : "https://api.weather.gov/offices/SEW"
forecastZone : "https://api.weather.gov/zones/forecast/WAZ558"

and
.relativeLocation.properties:
>city : "Seattle"
state : "WA"

As an added bonus we also have a 'county' key in our object with a url value, and when fetched to you can access it's .properties to get the name of the county!
>"properties": {
....
"type": "county",
"name": "King",
....
}

As you can see we have the gridpoints already put in and therefore a complete url for our next fetch. Now we simply need to fetch to the next url and, if desired, save our city and state to display on page.

Our next fetch should be done automatically after the original fetch's promise has resolved. We can use a .then to start the new fetch.

```
function getPoints(location) {
    let correctedLocation = correctInput(location);
    let url = `https://api.weather.gov/points/${correctedLocation}`;
    fetch(url)
        .then(res => {
            console.log(res.status);
            return res.json();
        })
        .then(dataObj => {
            fetch(dataObj.properties.forecast)
                .then(res => res.json())
                .then(data => { 
                    renderCards(data.properties.periods);
                });
            });

}
```

As you can see we decided to use the forecast url. This returns an array containing 14 weather data objects for day and night forecasts for the next week. Also included is an icon you can use in your website, even including a rain percentage if the chance is over 20%!
an example of the weather data we got looks something like

> {
number: 1, 
name: 'Tonight', 
startTime: '2023-03-05T20:00:00-08:00', 
endTime: '2023-03-06T06:00:00-08:00', 
isDaytime: false, …}
detailedForecast: "A chance of rain showers before 3am. Mostly cloudy. Low around 34, with temperatures rising to around 36 overnight. South wind 3 to 10 mph. Chance of precipitation is 40%. New rainfall amounts less than a tenth of an inch possible."
dewpoint: {unitCode: 'wmoUnit:degC', value: 2.7777777777777777}
endTime: "2023-03-06T06:00:00-08:00"
icon: "https://api.weather.gov/icons/land/night/rain_showers,40/rain_showers,30?size=medium"
isDaytime: false
name: "Tonight"
number: 1
probabilityOfPrecipitation: {unitCode: 'wmoUnit:percent', value:40}
relativeHumidity: {unitCode: 'wmoUnit:percent', value: 94}
shortForecast: "Chance Rain Showers"
startTime: "2023-03-05T20:00:00-08:00"
temperature: 34
temperatureTrend: "rising"
temperatureUnit: "F"
windDirection: "S"
windSpeed: "3 to 10 mph"

so now we have the location from the first request (state, city, county), and we have 14 objects containing 12 hour periods for the next week. Of course, if your project needs something like the hourly forecast you're going to be using a different second fetch request, you're going to have more or less returned objects in the array, and your object's data may look a bit different. 

The weather.gov API has a ton of data, and many methods to access it. This is just scratching the surface, I only included some of the urls from the first request, and even the first fetch is only one of the API's many urls you can fetch to. The full documentation is located [HERE](https://www.weather.gov/documentation/services-web-api).

Thank you for reading! This is my first post and I will be making more in the future, both as a student at Flatiron and in my career!