我已经在这个代码上工作了一段时间了,但我一直陷入一个漏洞,它是一个带有 API 的天气应用程序;这是代码:
所有链接均已正确链接。四天的预测不会显示在
inneHTMl
和 console.log 中,但是如果我打印 createWeatherCard
,它会打印出来,但没有数据。
代码片段
const searchButton = document.getElementById("searchBtn");
const cityInput = document.getElementById("cityInput");
const weatherCardsDiv = document.getElementById("weather-cards");
const API_KEY = "d292bd950ad1111c4da438d7967f0848";
const createWeatherCard = (weatherItem) => {
return`
<div class="bg-slate-400 rounded p-3 card">
<div class="border border-dashed border-2 border-slate-900 rounded p-4">
<div class="text-center font-bold">(${weatherItem.dt_txt.split(" ")[0]})</div>
<div class="relative mb-4">
<img src="https://openweathermap.org/img/wn/${weatherItem.weather[0].icon}@4x.png" alt="cloud" class="w-[5rem] m-auto">
<h4 class="text-center">Moderate Rain</h4>
</div>
<div class="flex justify-between mb-2">
<h4>Temp -</h4>
<p class="text-xl font-bold mb-px">${(weatherItem.main.temp - 273.15).toFixed(2)}*C</p>
</div>
<div class="flex justify-between mb-2">
<h4>Wind -</h4>
<p class="text-xl font-bold mb-px">${weatherItem.wind.speed} M/S</p>
</div>
<div class="flex justify-between ">
<h4>Humidity -</h4>
<p class="text-xl font-bold mb-px">${weatherItem.item.main.humidity}%</p>
</div>
</div>
</div>
`;
}
const getWeatherDetails = (cityName, lat, lon) => {
const WEATHER_API_URL = `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&appid=${API_KEY}`;
fetch(WEATHER_API_URL).then(res => res.json()).then(data => {
const uniqueForecastDays = [];
const fourDaysForecast = data.list.filter(forecast => {
const forecastDate = new Date(forecast.dt_txt).getDate();
if(!uniqueForecastDays.includes(forecastDate)) {
return uniqueForecastDays.push(forecastDate);
}
});
cityInput.value = "";
weatherCardsDiv.innerHTML = "";
console.log(fourDaysForecast);
fourDaysForecast.forEach(weatherItem => {
weatherCardsDiv.insertAdjacentHTML("beforeend", createWeatherCard(weatherItem));
})
}).catch(() => {
// alert("An error occurred when fetching the data");
});
}
const getCity = () => {
const cityName = cityInput.value.trim();
if(!cityName) return;
const GEOCODING_API_URL = `http://api.openweathermap.org/geo/1.0/direct?q=${cityName}&limit=1&appid=${API_KEY}`;
fetch(GEOCODING_API_URL).then(res => res.json()).then(data => {
if(!data.length) return alert(`No Data found for ${cityName}`);
const { name, lat, lon} = data[0];
getWeatherDetails(name, lat, lon);
}).catch(() => {
alert("An error occurred while fetching the data")
});
}
searchButton.addEventListener("click", getCity);
searchButton.click();
<label for="cityInput">City</label>
<input id="cityInput" type="text" value="Rome">
<input type="button" id="searchBtn" value="Search">
<div id="weather-cards"></div>
<script src="https://cdn.tailwindcss.com"></script>
错误在于您的
createWeatherCard
函数,以及您如何从 humidity
获取 weatherItem
信息。
而不是
<p class="text-xl font-bold mb-px">${weatherItem.item.main.humidity}%</p>
这样做
<p class="text-xl font-bold mb-px">${weatherItem.main.humidity}%</p>
此外,请务必在
http
函数中将 https
替换为 getCity()
。
附录(按照@Yogi 在评论中的建议)
尝试
createWeatherCard
时,您的代码会默默失败,因为 weatherItem.item.main.humidity
不存在。我们怎么知道呢?首先,错误捕获需要稍微调整,如下所示:
// ... rest of the code
fetch(WEATHER_API_URL).then(res => res.json()).then(data => {
// ... rest of the code
fourDaysForecast.forEach(weatherItem => {
weatherCardsDiv.insertAdjacentHTML("beforeend", createWeatherCard(weatherItem));
})
}).catch((err) => { // <-- this is the first addition
console.log(err.message); // <-- this is the second addition (or you can use alert(err.message);
// alert("An error occurred when fetching the data");
});
// ... rest of the code
这将告诉我们这一点
weatherItem.item is undefined
。但真的是这样吗?让我们在开始循环后立即将整个 weatherItem
记录到控制台,并进行检查。
// ... rest of the code
fourDaysForecast.forEach(weatherItem => {
console.log(weatherItem); // <-- this is what we added
weatherCardsDiv.insertAdjacentHTML("beforeend", createWeatherCard(weatherItem));
});
// ... rest of the code
浏览器控制台向我们展示了这一点:
{
"dt": 1706367600,
"main": {
"temp": 288.47,
"feels_like": 287.55,
"temp_min": 288.47,
"temp_max": 288.96,
"pressure": 1027,
"sea_level": 1027,
"grnd_level": 1023,
"humidity": 57,
"temp_kf": -0.49
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"clouds": {
"all": 0
},
"wind": {
"speed": 0.98,
"deg": 342,
"gust": 1.57
},
"visibility": 10000,
"pop": 0,
"sys": {
"pod": "d"
},
"dt_txt": "2024-01-27 15:00:00"
}
从那里开始,很明显我们可以做到(正如您所做的那样):
weatherItem.dt_txt.split(" ")[0]
weatherItem.weather[0].icon
(weatherItem.main.temp - 273.15).toFixed(2)
weatherItem.wind.speed
因为键
dt_txt
、weather
、main.temp
和 wind.speed
存在于 weatherItem
对象内。
但是,没有
item
键。我们正在寻找的 - humidity
- 不是您 weatherItem
的一级密钥。 main
键保存有关湿度的信息。这就是为什么(在您的设置中)正确的做法是通过执行 weatherItem.main.humidity
来获取湿度。