reactjs - 尝试使用 OpenWeatherMaps API 为城市的无效获取生成警报
问题描述
因此,我正在尝试为尝试通过 OpenWeatherMaps API 访问无效城市的天气数据的用户生成警报。
我大部分时间都在。但是,当我对此进行测试时,会发生两件事:
- 浏览器生成正确的警报。
但是,一旦您单击警报的确认按钮...
- “未处理的拒绝(TypeError):无法解构'(中间值)'的属性'数据',因为它未定义。”
这是我目前正在使用的代码:
const fetchWeather = async (query) => {
const { data } = await axios.get(
URL,
{
params: {
q: query,
units: "metric",
APPID: API_KEY,
},
}).catch (function (error) {
alert(error.response.data.message)
})
};
完整代码:
Search.jsx 组件:
import React, { useState } from "react";
import fetchWeather from "../api/fetchWeather";
import { makeStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import InputAdornment from '@material-ui/core/InputAdornment';
import SearchIcon from '@material-ui/icons/Search';
const Search = () => {
let [displayResults, setDisplayResults] = useState(false);
let [query, setQuery] = useState("");
let [feelsLike, setFeelsLike] = useState(0);
let [mainTemp, setMainTemp] = useState(0);
let [description, setDescription] = useState("");
let [main, setMain] = useState("");
let [iconID, setIconID] = useState("");
let [windSpeed, setWindSpeed] = useState("");
let [windGust, setWindGust] = useState("");
let [windDirection, setWindDirection] = useState("");
let [name, setName] = useState("");
let [country, setCountry] = useState("");
const useStyles = makeStyles((theme) => ({
button: {
backgroundColor: "#FDB124",
color: "black",
fontFamily: "Mortal Kombat",
"&:hover": {
background: "#B57602",
},
},
root: {
"& > *": {
display: 'flex',
margin: theme.spacing(1),
// width: "25ch",
},
input: {
color: "white",
},
primary: {
backgroundColor: "#FDB124",
},
"& label.Mui-focused": {
color: "#FDB124",
},
"& label": {
color: "#FDB124",
fontFamily: "Mortal Kombat",
},
"& input": {
color: "#FDB124",
fontFamily: "Mortal Kombat",
},
"& .MuiInput-underline:after": {
borderBottomColor: "#FDB124",
},
"& .MuiOutlinedInput-root": {
"& fieldset": {
borderColor: "#FDB124",
},
"&:hover fieldset": {
borderColor: "#FDB124",
},
"&.Mui-focused fieldset": {
borderColor: "#FDB124",
},
},
},
}));
const weatherSearch = async (e) => {
if (e.key === "Enter") {
const data = await fetchWeather(query);
setDisplayResults(true);
setFeelsLike(data.main.feels_like);
setMainTemp(data.main.temp);
setDescription(data.weather[0].description);
setMain(data.weather[0].main);
setIconID(data.weather[0].icon);
setWindSpeed(data.wind.speed);
setWindGust(data.wind.gust);
setWindDirection(data.wind.deg);
setName(data.name);
setCountry(data.sys.country);
setQuery("");
}
};
const classes = useStyles();
return (
<div>
<h1 className="cityChoose">CHOOSE YOUR CITY:</h1>
<TextField
id="outlined-basic"
label="Enter City"
variant="outlined"
color="secondary"
size="small"
spellCheck="false"
className={classes.root}
value={query}
onChange={(e) => setQuery(e.target.value)}
onKeyPress={weatherSearch}
InputProps={{
startAdornment: (
<InputAdornment position="start" style={{color: "#FDB124"}}>
<SearchIcon />
</InputAdornment>
),
}}
/>
{displayResults ? null : <h4>Example: Chicago, IL, US</h4>}
{displayResults ? (
<>
<h1>The current weather in {name}, {country} is:</h1>
<span>
<div>
{description}
<br />
<img
src={"http://openweathermap.org/img/wn/" + iconID + "@2x.png"}
/>
</div>
<h2>Temperature:</h2>
<br />
<div>
{(mainTemp * 1.8 + 32).toFixed(1)} °F / {mainTemp.toFixed(1)}{" "}
°C
</div>
<br />
<br />
<h2>Winds:</h2>
<div>Wind Direction: {windDirection}</div>
<div>Wind Speed: {windSpeed} MPH</div>
<div>Wind Gusts: {windGust} MPH</div>
</span>
</>
) : null}
</div>
);
};
export default Search;
fetchWeather.jsx:
import React from "react";
import axios from "axios";
const URL = "https://api.openweathermap.org/data/2.5/weather";
const API_KEY = "*key is here*";
const fetchWeather = async (query) => {
const { data } = await axios.get(
URL,
{
params: {
q: query,
units: "metric",
APPID: API_KEY,
},
}).catch (function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
console.log(error.request);
} else {
console.log("Error: ", error.message);
}
});
console.log(data);
return data;
};
export default fetchWeather;
解决方案
好的,所以您遇到的问题与 axios 引发错误并且不返回带有 key data
back to的对象的事实有关const { data } = await axios.get(
。解决这个问题非常简单。
它不能data
从你的错误 axios 调用中解构的原因是你没有在 catch 块中容纳它
.catch (function (error) {
alert(error.response.data.message)
})
您的 catch 块应如下所示:
.catch (error => {
return {data: error.response.data ? error.response.data : 'No data'}
}
)
所以你的函数的最终(和工作)版本fetchWeather
是......
const fetchWeather = async (query) => {
const { data } = await axios.get(
'https://httpstat.us/400',
{
params: {
q: query,
units: "metric",
APPID: 'XXXXXXXX',
},
})
.catch (error => {
return {data: error.response.data ? error.response.data : 'No data'}
}
)
console.log(data)
};
您可以使用以下两个测试 URL 进行尝试:
https://httpstat.us/200 returns 200 OK
https://httpstat.us/400 returns 400 Bad Request
后者将触发catch
.
请记住,如果您调用的域无法解析为 ip(例如http://hskjfhshgsg.com/api/sss/sss或类似的东西),我的代码会抛出错误。
推荐阅读
- c - 将用户输入读取到数组中,直到其最大大小
- elasticsearch - 在 Elasticsearch 中使用索引值作为前缀
- c - C中的数组和指针中的分段错误
- python - LDA Gensim Mallet 将 alpha 设置为“自动”
- java - 如何实现可缩放的绘图区域?
- jquery - Select2 取消选择任何选项
- javascript - 如何访问 JavaScript Map 中的(数组)键?
- javascript - 在 puppeteer 中无限向下滚动不起作用
- mongodb - 跨区域创建 StatefulSet 集群
- mysql - 如何使用 TYPO3 queryBuilder 发出正则表达式请求