简体   繁体   中英

For-loop issue? Uncaught (in promise) TypeError: cannot set properties of null (setting 'inner text)

I'm trying to use a for-loop to iterate through data from open weather map API that returns data from a 5-day forecast. Currently I am building weather app that provides not only current city data provided by user input, but also the weekly data of that same city. As of now all my current weather data is fetched and displaying from the API correctly. I chose to use the for loop to get the minimum and maximum temperatures as well as the weather icons for each day of the week. No problems are displaying as of now within my code itself. However, when I run the FetchWeeklyWeatherInfo function in my browser console it returns an error that reads: uncaught (in promise) TypeError: cannot set properties of null (setting 'inner text) at weather app.js:33:86 while for-loops are admittedly a little bit challenging for me I am simply not seeing the issue here.

JavaScript:

function fetchCurrentWeatherInfo (city) {
const currentWeatherUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${currentWeatherApiTag}`;
fetch(currentWeatherUrl)
.then((response) => response.json())
.then((data) => unveilCurrentWeather(data));

};   

 function unveilCurrentWeather (data) {
 const {name} = data;
 const {icon} = data.weather[0];
 const {description} = data.weather[0];
 const {temp} = data.main;
 const {humidity} = (data.main);
 const {speed} = data.wind;
 console.log(name, icon, description, temp, humidity, speed);
 document.querySelector("#City").innerText = "Weather in " + name;
 document.querySelector(".weather-icon").src =`http://openweathermap.org/img/wn/${data.weather[0].icon}.png`;
 document.querySelector("#CityWeatherDescription").innerText = description;
 document.querySelector("#Temperature").innerText = temp + " °F";
 document.querySelector (".humidity-weather-stat").innerText = "Humidity : " +  humidity + "%";
 document.querySelector(".wind-speed-weather-stat").innerText = "Wind Speed : " + speed + "m/hr";

};

function fetchWeeklyWeatherInfo (city) {
    const weekWeatherUrl = `https://api.openweathermap.org/data/2.5/forecast?q=${city}&units=imperial&appid=${weekForecastApiTag}`;
    fetch(weekWeatherUrl)
    .then((response) => response.json())
    .then(data => {
        for(i=0; i<5; i++) {
        document.querySelector(".day-of-the-week" +(i+1)+".temp-high").innerText = "High :" + Number(data.list[0].main.temp_max -74.57).toFixed(2) + "°F";
    }
    for(i=0; i<5; i++) {
        document.querySelector(".day-of-the-week" +(i+1)+".temp-low").innerText = "Low :" + Number(data.list[0].main.temp_min -74.57).toFixed(2) + "°F";
    }
    for(i=0; i<5; i++) {
        document.querySelector(".weather-icon" +(i+1)).src = `http://openweathermap.org/img/wn/${data.list[0].weather[0].icon}.png`;
}
});


function searchCurrentWeather () {
fetchCurrentWeatherInfo(document.querySelector("#Search-Bubble").value);
};


document.getElementById("SearchBtn").addEventListener("click", function () {
searchCurrentWeather();

});

document.getElementById("Search-Bubble").addEventListener("keyup", function (event) {
if (event.key === "Enter") {
searchCurrentWeather();
}
});

};

This could be something simple or more intricate but I need a fresh set of eyes on the problem, thanks!

Just gonna take a guess here but try to put your DOM dependant functions and vars in a onloaded event of some kind like below:

const el = document.getElementById("el") // NOT AVAILABLE

window.addEventListener("load", function() {
   const el = document.getElementById("el") // YAY AVAILABLE
})

Also for some copy paste action:

function doSomething() {
  console.info('DOM loaded');
}

if (document.readyState === 'loading') {  // Loading hasn't finished yet
  document.addEventListener('DOMContentLoaded', doSomething);
} else {  // `DOMContentLoaded` has already fired
  doSomething();
}

So you can put your functions up top in yur script, and then when you want to call them, or when you want to declare a variable that is equal to some DOM element, you put that in the load event.

// SearchBtn wont exist out here - put inside onload event!!

window.addEventListener("load", function() {
   // SearchBtn & your other DOM elements WILL exist in here!!
   document.getElementById("SearchBtn").addEventListener("click", 
      function () {
          searchCurrentWeather();
     });

document.getElementById("SearchBubble").addEventListener("keyup", 
function (event) {
    if (event.key === "Enter") {
        searchCurrentWeather();
    }
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM