不打印天气预报

问题描述 投票:0回答:1

我已经在这个代码上工作了一段时间了,但我一直陷入一个漏洞,它是一个带有 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>

javascript tailwind-css openweathermap
1个回答
1
投票

错误在于您的

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
来获取湿度。

© www.soinside.com 2019 - 2024. All rights reserved.