I am working with OpenWeatherMap API to calculate the sum of precipitation for the previous 5 days. I have no issues accessing values such as humidity or temp, but I am having issues totaling all rain values of the previous 5 days. rain is only available in the object response with it is actually measured. here is an example of what it look like when rain is measured:
You can see that rain is under hourly.18.rain['1h']. My issue comes in totaling them all.
Here is my full code:
//converts current unix date from miliseconds to seconds and subtracts seconds from variable daysAgo
function getDaysAgo(days) {
return Math.floor((Date.now() / 1000) - (86400 * days)) //returns date of privious 5 days from now.
}
//fetchs historic hourly weather data for rain.
async function getDataForDaysAgo(days) {
let daysAgo = getDaysAgo(days) //nest getDaysAgo function to variable
const apiURL = `http://api.openweathermap.org/data/2.5/onecall/timemachine?lat=29.8833&lon=-97.9414&dt=${daysAgo}&appid=` //calls historic weather api using privious days
const apiResponse = await fetch(apiURL) //fetch data
const responseJson = await apiResponse.json() //converts data to json
var total = 0
console.log(responseJson);
responseJson.hourly.forEach(hour => { //loops through each 1hr record of 24
//if no rain is recorded, rain data is not available. system reprots: NaN
if (isNaN(hour.rain['1h'])){
hour.rain['1h'] = 0 //if rain is NaN, change that value to 0.
}//else(total += hour.rain);
else{
total += hour.rain['1h']
}//otherwise sum all available rain values.
//total += hour.rain
});
console.log(`getDataForDaysAgo(${days}) returns ${total}`) //logs total rain values for each 24hr period
return total
}
//call above fetch function with appropriate historic 'daysAgo'
async function getDataSums() {
var data1 = await getDataForDaysAgo(5)
var data2 = await getDataForDaysAgo(4)
var data3 = await getDataForDaysAgo(3)
var data4 = await getDataForDaysAgo(2)
var data5 = await getDataForDaysAgo(1)
return data1 + data2 + data3 + data4 + data5; //returns sum of 5 day rain values
}
getDataSums().then(result => { //waits for getDataSums and return result
var totalRainInches = parseFloat((result)*25.4); //converts to mm to inches
document.getElementById('precip5day').innerHTML = "Five Day Precipication Accumulation:"
document.getElementById('precipValue').innerHTML = totalRainInches.toFixed(2) + "″"
//proof of concept conditional statment that gives recommendations for trail use
//based on 5 day rain totals and writes to index.html file
if (totalRainInches <= 0.50){
document.getElementById('conditions').innerHTML = "Hiking and mountain biking should be okay"
} else if (totalRainInches < 3 ){
document.getElementById('conditions').innerHTML = "Due to recent rain activity, use best judgement when hiking or mountain biking"
} else if (totalRainInches > 7 ){
document.getElementById('conditions').innerHTML = "Due to heavy rainfall, trails should not be used"
}else {
document.getElementById('conditions').innerHTML = "Something broke :("
}
});
I had luck totaling all of the humidity values with:
responseJson.hourly.forEach(hour => {
if (isNaN(hour.humidity)){
hour.humidity = 0
}
else{
total += hour.humidity
}
but when it comes to the rain values I am coming up empty handed and receiving error messages that the rain variable is undefined. Any thought? Thanks! Also, here is a link to a previous question that got me this far.
Are you sure that rain
is present in all hours from 0 to 23? If it's missing you'd get "Uncaught TypeError: Cannot read property '1h' of undefined"
like in my sample below. If you check for it, it should sum it up alright.
// prep 24 hours with rain and humidity
var hourly = []
for (let i = 0; i < 24; i++) {
hourly[i] = {
rain: {
'1h': 0.5
},
humidity: 2.2
}
}
// your code in a function
function sumRain(hourly) {
var total = 0;
hourly.forEach(hour => {
// uncomment the next line to check for 'rain' being present
// if (hour.rain)
if (isNaN(hour.rain['1h'])) {
hour.rain['1h'] = 0
} else {
total += hour.rain['1h']
}
});
return total;
}
console.log(sumRain(hourly))
// modify hourly so rain is missing from one of the hours
delete hourly[11].rain;
// now sumrain throws an exception unless you check for hour.rain being present before trying to sum it up
console.log(sumRain(hourly))