雅虎天气 API 引发 'forEach' 错误

Yahoo Weather API throws 'forEach' error

我决定继续使用雅虎天气 api,试图让它显示位置,然后显示天气。

app.js代码:

** 注意我将 api url 位置替换为 'query'**

var express = require("express");
var app = express();
var request = require("request");

app.set("view engine", "ejs");


app.get("/", function(req, res){
    res.render("weatherSearch"); 
});

app.get("/results", function(req, res){
   var query = req.query.searchTerm;
   var url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22"+query+"%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"

   request(url, function(error, response, body){
            if(!error && response.statusCode == 200){
                var data = JSON.parse(body);
                res.render("results", {data: data});
            }
   });
});


app.listen(process.env.PORT, process.env.IP, function(){
   console.log("Server Connected"); 
});

weatherSearch.ejs :

<h1>Where would you like to check the weather?<h1>

<form action ="/results" method="GET">

    <input type="text" placeholder="Enter the city here!" name="searchTerm">
    <input type="submit">


</form> 

results.ejs

<h1>The Weather is:</h1>

<ul>
    <% data["query"].forEach(function(weather){ %>
    <li>
        <strong>
            <% weather["location"] %>
        </strong>
    </li>
<% }) %>

</ul>

<a href="/">Search Again!</a>

我从控制台收到的错误是:

Server Connected
TypeError: /home/ubuntu/workspace/WeatherSearchAPP/views/results.ejs:4
    2| 
    3| <ul>
 >> 4|     <% data["query"].forEach(function(weather){ %>
    5|     <li>
    6|         <strong>
    7|             <% weather["location"] %>

data.query.forEach is not a function
    at eval (eval at compile (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:618:12), <anonymous>:11:22)
    at returnedFn (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:653:17)
    at tryHandleCache (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:251:36)
    at View.exports.renderFile [as engine] (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/ejs/lib/ejs.js:482:10)
    at View.render (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/view.js:135:8)
    at tryRender (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/application.js:640:10)
    at EventEmitter.render (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/application.js:592:3)
    at ServerResponse.render (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/express/lib/response.js:1008:7)
    at Request._callback (/home/ubuntu/workspace/WeatherSearchAPP/app.js:19:21)
    at Request.self.callback (/home/ubuntu/workspace/WeatherSearchAPP/node_modules/request/request.js:185:22)

yahoo weather api:(目前在 'london' 中提供天气),所以如果您将其复制到您的网络浏览器中,您将看到大量与天气有关的信息在伦敦。

https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22london%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys

如果有人对我做错的事情有任何建议,将不胜感激!!

API returns 格式为 { "query": { ...} } 的数据,将其转换为 JSON 对象,最终得到 query 对象,不是数组。查看 query 对象本身,它似乎具有 countresults 属性(并且 results 属性 看起来也像一个对象)。但是,您的特定查询只会产生一个结果,因此假设在您有多个结果的情况下会产生一个数组,我认为您需要结合使用这两个属性来准确解析数据,例如

const data = JSON.parse(body);
const { count, results } = data.query;
res.render("results", { 
  results: count > 1 ? results : [results]  // wrap in an array of only single result
});

那么在你看来

<% results.forEach(...) %>

'forEach' 是数组方法,Yahoo Weather API 没有 return 键 "query" 下的数组。每个 API 都是不同的,每个请求可以产生不同的结构化 JSON 数据。

如您所述,您可以打开此 link 检查 Yahoo Weather API 响应的结构。例如,如果你想访问城市名称,你可以使用

 <%= data.query.results.channel.location.city %>

你得到一个预测数组 returned 为即将到来的几天,你可以在上面使用 forEach 循环,因为它是一个数组:query.results.channel.item.forecast

在你想要循环遍历 JS 中的对象的场景中,你可以使用 for...in 循环:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in