未捕获(承诺)类型错误:result.main 未定义

时间:2021-05-31 14:16:30

标签: javascript api promise fetch

我正在从事一个基于天气的 API 项目以提高我的技能,但在获取数据时出现错误:

Uncaught (in promise) TypeError: result.main is undefined

这里是负责从 API 获取数据的函数:

async function fetchData(cityName) {
  const API_KEY = 'MY_API_TOKEN';

  const fetchRes = {
    method: 'GET',
    redirect: 'manual',
    mode: 'cors',
  };
  const response = await fetch(
    `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=${API_KEY}`,
    fetchRes
  );
  const result = await response.json();
  const data = result.main.temp;
  console.log(data);
}

使用此调用修复

fetchData("london");

这里我使用另一个输入和搜索按钮获取城市名称

注意:我出于安全原因隐藏了我的 API 令牌密钥,所以这不是问题

1 个答案:

答案 0 :(得分:2)

单独的效果

return 结果而不是记录它 -

async function fetchData(cityName) {
  const API_KEY = 'MY_API_TOKEN';

  const fetchRes = {
    method: 'GET',
    redirect: 'manual',
    mode: 'cors',
  };
  const response = await fetch(
    `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=${API_KEY}`,
    fetchRes
  );
  const result = await response.json();
  return result.main.temp // <-- return the result
}

现在附加效果和错误处理程序 -

fetchData(...)
  .then(console.log)      // <- receives data
  .catch(console.error)   // <- receives error

您可以在单个 .then 中附加效果和错误处理程序 -

fetchData(...)
  .then(console.log, console.error) // <- same behaviour as above

单独的问题

我建议分离关注点,以便更容易地读/写你的函数 -

const getJSON = (url, opts = {}) =>
  fetch(url, opts).then(r => r.json())

现在你不必每次想查询一些 JSON 时都重复自己 -

async function fetchData(cityName) {
  const API_KEY = 'MY_API_TOKEN';

  const url = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=${API_KEY}`

  const opts = {
    method: 'GET',
    redirect: 'manual',
    mode: 'cors',
  };

  const result = await getJSON(url, opts) // <- reusable function
  return result.main.temp
}

网址处理

我建议不要使用字符串构建 URL。而是使用 URL searchParams API 以编程方式构建事物 -

async function fetchData(cityName) {
  const API_KEY = 'MY_API_TOKEN'

  // use URL api
  const u = new URL("https://api.openweathermap.org/data/2.5/weather")
  u.searchParams.set("q", cityName)
  u.searchParams.set("appid", API_KEY)

  const opts = {...}

  const result = await getJSON(u, opts) // <- pass URL object
  return result.main.temp
}

如您所见,每次需要设置/修改某些 URL 参数时都必须编写所有这些内容会很烦人。应用上面的教训,我们写href -

function href(url, params = {}) {
  const u = new URL(u)
  for (const [key, value] of Object.entries(params))
    u.searchParams.set(key, value)
  return u.toString()
}

现在你可以避免在常用函数中出现重复和容易出错的代码 -

async function fetchData(cityName) {
  const API_KEY = 'MY_API_TOKEN'

  // use our href helper
  const u = href("https://api.openweathermap.org/data/2.5/weather", {
    q: cityName,
    appid: API_KEY
  })

  // use getJSON helper
  const result = await getJSON(u, {...})
  return result.main.temp
}
fetchData("someCity").then(console.log, console.error)