UnclePete
UnclePete

Reputation: 25

For loop not going beyond first day in loop

I am trying to create a for loop to get the min and max temperature of each day and output it. I am using Open Weather API. I have attached an image of what the data looks like when called. Please feel free to ask any questions. I don't know what types of things to clarify. Here is my javascript.

fetch('https://api.openweathermap.org/data/2.5/onecall?lat=43.6121&lon=-116.3915&exclude=hourly,minutely&units=imperial&APPID=98cbc04c44e9fc2905a70710f2643e4e')
.then((response) => response.json())
.then((jsObject) => {
    console.log(jsObject);

let temp = jsObject.current.temp;
let minTemp = jsObject.daily[0].temp.min;
let maxTemp = jsObject.daily[0].temp.max;

document.getElementById('condition').textContent = jsObject.current.weather[0].main;
document.getElementById('temp-min').textContent = Math.round(minTemp);
document.getElementById('temp-max').textContent = Math.round(maxTemp);
document.getElementById('temp-current').textContent = Math.round(temp);

    
    var weekday = new Array(7);
    weekday[0] = "Sun";
    weekday[1] = "Mon";
    weekday[2] = "Tue";
    weekday[3] = "Wed";
    weekday[4] = "Thu";
    weekday[5] = "Fri";
    weekday[6] = "Sat";

    var data = jsObject.daily;
    var dayOfWeek = document.getElementsByClassName("forecast-day");
    var weatherIcon = document.getElementsByClassName("weatherIcon");
    var tempMax = document.getElementsByClassName("forecast-max");
    var tempMin = document.getElementsByClassName("forecast-min");

    for (var i = 0; i < data.length; i++) {
        var d = new Date(data[i]);
        dayOfWeek[i].textContent = weekday[d.getDay()];

        const imagesrc = 'https://openweathermap.org/img/w/' + data[i].weather[i].icon + '.png';
        const description = data[i].weather[i].description;
        weatherIcon[i].setAttribute('src', imagesrc);
        weatherIcon[i].setAttribute('alt', description);

        tempMax[i].innerHTML = Math.round(data[i].temp.max) + " &#176;F";
        tempMin[i].innerHTML = Math.round(data[i].temp.min) + " &#176;F";

    }

https://i.sstatic.net/boWF9.png

Upvotes: 1

Views: 100

Answers (2)

Kinglish
Kinglish

Reputation: 23654

Here is a working snippet of your code. You weren't accessing the date value correctly var d = new Date(data[i].dt); (not new Date(data[i])) which was causing the other date-dependent items to fail. Once that was fixed, the day of the week needed adjusting to weekday[d.getDay()+i];. The data[i].weather[i] references needed were incorrect (weather had just one index) data[i].weather[0].

To test, I generated the divs and img elements so the format is off, but you can see they all get populated.

/* this section is just to generate the elements for testing */
let a = ['condition', 'temp-min', 'temp-max', 'temp-current'];
a.forEach(b => {
  document.querySelector('#boxes').innerHTML += "<div id='" + b + "'>---" + b + "---</div>";
})
a = ["forecast-day", "forecast-max", "forecast-min"];
a.forEach(b => {
  for (let x = 0; x < 7; x++) document.querySelector('#boxes').innerHTML += "<div class='" + b + "'>---" + b + "---</div>";
})
a = ["weatherIcon"];
a.forEach(b => {
  for (let x = 0; x < 7; x++) document.querySelector('#boxes').innerHTML += "<img class='" + b + "'>";
})

/* Your code */
fetch('https://api.openweathermap.org/data/2.5/onecall?lat=43.6121&lon=-116.3915&exclude=hourly,minutely&units=imperial&APPID=98cbc04c44e9fc2905a70710f2643e4e')
  .then((response) => response.json())
  .then((jsObject) => {
    let temp = jsObject.current.temp;
    let minTemp = +jsObject.daily[0].temp.min;
    let maxTemp = +jsObject.daily[0].temp.max;

    document.getElementById('condition').textContent = jsObject.current.weather[0].main;
    document.getElementById('temp-min').textContent = Math.round(minTemp);
    document.getElementById('temp-max').textContent = Math.round(maxTemp);
    document.getElementById('temp-current').textContent = Math.round(temp);

    var weekday = new Array(7);
    weekday[0] = "Sun";
    weekday[1] = "Mon";
    weekday[2] = "Tue";
    weekday[3] = "Wed";
    weekday[4] = "Thu";
    weekday[5] = "Fri";
    weekday[6] = "Sat";

    var data = jsObject.daily;
    var dayOfWeek = document.getElementsByClassName("forecast-day");
    var weatherIcon = document.getElementsByClassName("weatherIcon");
    var tempMax = document.getElementsByClassName("forecast-max");
    var tempMin = document.getElementsByClassName("forecast-min");
    for (var i = 0; i < data.length; i++) {
      var d = new Date(data[i].dt);
       dayOfWeek[i].textContent = weekday[d.getDay()+i];
      const imagesrc = 'https://openweathermap.org/img/w/' + data[i].weather[0].icon + '.png';
      const description = data[i].weather[0].description;
      weatherIcon[i].setAttribute('src', imagesrc);
      weatherIcon[i].setAttribute('alt', description);

      tempMax[i].innerHTML = Math.round(data[i].temp.max) + " &#176;F";
      tempMin[i].innerHTML = Math.round(data[i].temp.min) + " &#176;F";

    }
  })
div {
  margin: 2px;
  border: 1px solid #ccc;
}
<div id='boxes'></div>

Upvotes: 0

raina77ow
raina77ow

Reputation: 106385

According to what I see in that server's response, weather property of each element of daily array has just one element. Yet your code is trying to access more than that with data[i].weather[i].icon expression, starting from the second iteration of the loop (when i is 1).

The code blows then, as data[i].weather[i] is undefined, and you're trying to work with that as with an object (accessing its icon property). As all of that is executed inside then, either you should see Unhandled promise rejection... in your console or (and that's really bad) it just fails silently because of some forgiving catch handler.

Solution seems to be rather simple: replace all data[i].weather[i] with data[i].weather[0] parts. Or (much better) just store this in some temp variable, like this:

const weather = data[i].weather[0];

const imagesrc = 'https://openweathermap.org/img/w/' + weather.icon + '.png';
weatherIcon[i].setAttribute('src', imagesrc);
weatherIcon[i].setAttribute('alt', weather.description);

As a sidenote, I'd suggest refactoring your code so that it iterates over the collected DOM elements, and not the server's response. There's a chance for mismatch, as there's 8 elements (days) there, but it's hard to say how many .forecast-day, .forecast-max, etc... elements are in your DOM.

Upvotes: 1

Related Questions