我通过EJS将API返回的数据传递给客户端。我在客户端访问返回的JSON数组失败了。在服务器端,我成功地向客户端传递了返回的数据,如下所示:
fetch(url)
.then(res => res.json())
.then(data => res.render('pages/search', {
venues: JSON.stringify(data.response.venues)
}))
.catch(err => {
console.log(err);
res.sendStatus(500);
});
我传递给客户端的返回JSON如下所示:
[
{
"id": "4bc20e29b492d13a9cdba660",
"name": "BBQ",
"contact": {
"phone": "555-555-555",
"formattedPhone": "555-555-555",
"twitter": "bbq",
"facebook": "162628917087420"
},
"location": {
"address": "XXXX US Hwy 48 North",
"lat": 22.089288703481692,
"lng": -80.97257354855537,
"labeledLatLngs": [
{
"label": "display",
"lat": 22.089288703481692,
"lng": -80.97257354855537
}
],
"postalCode": "333333",
"cc": "US",
"city": "CITY",
"state": "FL",
"country": "United States",
"formattedAddress": [
"XXXX US Hwy 48 North",
"CITY, FL 333333",
"United States"
]
},
"categories": [
{
"id": "4bf58dd8d48988d1df931735",
"name": "BBQ Joint",
"pluralName": "BBQ Joints",
"shortName": "BBQ",
"icon": {
"prefix": "https://ss3.4sqi.net/img/categories_v2/food/bbqalt_",
"suffix": ".png"
},
"primary": true
}
],
"verified": true,
"stats": {
"tipCount": 16,
"usersCount": 946,
"checkinsCount": 2087
},
"url": "https://www.sonnysbbq.com/location/store151",
"hasMenu": true,
"menu": {
"type": "Menu",
"label": "Menu",
"anchor": "View Menu",
"url": "https://www.sonnysbbq.com/menu/",
"mobileUrl": "https://www.sonnysbbq.com/menu/",
"externalUrl": "https://www.sonnysbbq.com/menu/"
},
"allowMenuUrlEdit": true,
"beenHere": {
"lastCheckinExpiredAt": 0
},
"specials": {
"count": 0,
"items": []
},
"storeId": "151",
"referralId": "v-1520220733",
"venueChains": [
{
"id": "556a31e2a7c8957d73d4874c"
}
],
"hasPerk": false
},
{
"id": "4bc20e29b492d13a9cdba660",
"name": "BBQ",
"contact": {
"phone": "555-555-555",
"formattedPhone": "555-555-555",
"twitter": "bbq",
"facebook": "162628917087420"
},
"location": {
"address": "XXXX US Hwy 48 North",
"lat": 22.089288703481692,
"lng": -80.97257354855537,
"labeledLatLngs": [
{
"label": "display",
"lat": 22.089288703481692,
"lng": -80.97257354855537
}
],
"postalCode": "333333",
"cc": "US",
"city": "CITY",
"state": "FL",
"country": "United States",
"formattedAddress": [
"XXXX US Hwy 48 North",
"CITY, FL 333333",
"United States"
]
},
"categories": [
{
"id": "4bf58dd8d48988d1df931735",
"name": "BBQ Joint",
"pluralName": "BBQ Joints",
"shortName": "BBQ",
"icon": {
"prefix": "https://ss3.4sqi.net/img/categories_v2/food/bbqalt_",
"suffix": ".png"
},
"primary": true
}
],
"verified": true,
"stats": {
"tipCount": 16,
"usersCount": 946,
"checkinsCount": 2087
},
"url": "https://www.sonnysbbq.com/location/store151",
"hasMenu": true,
"menu": {
"type": "Menu",
"label": "Menu",
"anchor": "View Menu",
"url": "https://www.sonnysbbq.com/menu/",
"mobileUrl": "https://www.sonnysbbq.com/menu/",
"externalUrl": "https://www.sonnysbbq.com/menu/"
},
"allowMenuUrlEdit": true,
"beenHere": {
"lastCheckinExpiredAt": 0
},
"specials": {
"count": 0,
"items": []
},
"storeId": "151",
"referralId": "v-1520220733",
"venueChains": [
{
"id": "556a31e2a7c8957d73d4874c"
}
],
"hasPerk": false
}
]
由于这是一个对象数组,并且这个数组中显然有两个主要对象,我希望能够像这样访问我的EJS页面上的数据:
<%= venues[0].location.lat =>
这根本不起作用。我什么都没得到,但我也没有错。但是,如果我这样做:
<%= venues %>
我可以将整个JSON响应呈现给页面。但为什么我不能专门访问具有索引值的数组?我的最终目标是能够从位置对象访问纬度和经度坐标。这就是我期望实现的目标:
<%= venues[0].location.lat %>
<%= venues[0].location.lng %>
注意:我将在for循环中工作,因此我可以遍历整个返回的JSON数组,但是对于这个示例,我将循环退出并将JSON响应缩短为两个主要对象。
答案 0 :(得分:1)
将其更改为:
fetch(url)
.then(res => res.json())
.then(data => res.render('pages/search', {
venues: data.response.venues
}))
.catch(err => {
console.log(err);
res.sendStatus(500);
});
模板期望模板变量作为JS类型而不是字符串化JSON传递。
答案 1 :(得分:0)
当您对JSON对象进行字符串化时,您将无法再访问任何对象键/值。
E.g。来自Mozilla:
JSON.stringify({x:5,y:6});
//'{“x”:5,“y”:6}'&lt; - 注意引号
现在,当您发送HTTP Request
时,必须对JSON Objects
进行字符串化,因为HTTP
无法保持JSON Object
的状态。
然而,express can,也就是视图引擎也可以。
要记住的重要一点是,视频引擎(在您的情况下为ejs
)会在插入HTTP Request
之后发送JSON Objects
或呈现页面。< /强>
答案 2 :(得分:0)
处理这个问题差不多48小时,它终于得到了解决。首先,感谢任何花时间帮助我的人,非常感谢!
基本上,我需要在将返回的API数据从服务器传递到客户端时使用JSON.stringify()
。一旦数据在客户端,我使用JSON.parse()
来包装字符串化的EJS变量:
服务器:
fetch(url)
.then(res => res.json())
.then(data => res.render('pages/search', {
userLat: latLng.lat,
userLng: latLng.lng,
venues: JSON.stringify(data.response)
}))
.catch(err => {
console.log(err);
res.sendStatus(500);
})
客户端:
<script>
var test = JSON.parse(<%- JSON.stringify(venues) %>);
//and a console.log that confirms I can access the data
console.log(test.venues)
</script>
我现在可以访问客户端数据中的对象,就像我最初预期的那样。我将此数据与Google Map API一起使用,我将在页面上使用此内联<script>
标记呈现地图。我很肯定没有办法将EJS传递的数据从服务器共享到客户端的外部JS文件,因此我选择了只使用内联<script>
的地图进行渲染。
但是,我不明白为什么当从已经字母化的服务器发送EJS数据时,我需要用JSON.stringify()
包装EJS变量。我真的很想知道为什么,而不仅仅是让我的事业认为它是黑魔法哈哈。
无论如何,这解决了我的问题!