
本文旨在解决在EJS模板中集成Mapbox时,因数据传递不当导致的TypeError: Cannot read properties of undefined (reading 'coordinates')错误。核心问题在于将JSON字符串化的对象再次用引号包裹,使其在客户端JavaScript中无法被正确解析为对象。通过移除EJS模板中JSON.stringify输出外部的额外引号,可确保数据作为有效的JavaScript对象字面量被直接赋值,从而使Mapbox能够正确访问地理坐标信息。
在开发基于Node.js和Express的应用时,经常需要将后端数据渲染到前端EJS模板中。当使用Mapbox GL JS库来展示地理位置信息时,一个常见的场景是将包含地理坐标的营地(campground)对象从服务器传递到客户端JavaScript。然而,在实践中,开发者可能会遇到Uncaught TypeError: Cannot read properties of undefined (reading 'coordinates')这样的错误。
这个错误通常发生在尝试访问Mapbox GL JS配置中的campground.geometry.coordinates时,表明campground变量在客户端JavaScript中并非预期的对象,或者其geometry属性为undefined。尽管后端数据结构正确,且EJS模板中的代码看似合理,但细微的语法错误可能导致前端脚本无法正确解析数据。
问题的核心在于EJS模板中数据传递的方式。原始代码如下:
<script>
const mapToken = '<%=process.env.MAPBOX_TOKEN%>';
const campground = '<%- JSON.stringify(campground) %>'; // 错误示例
</script>以及对应的客户端JavaScript文件showPageMap.js:
mapboxgl.accessToken = mapToken;
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: campground.geometry.coordinates, // 错误发生在这里
zoom: 8,
});
new mapboxgl.Marker()
.setLngLat(campground.geometry.coordinates)
.addTo(map);当EJS模板被渲染后,campground变量在浏览器前端的实际表现如下:
<script>
const mapToken = 'TOKEN';
const campground = '{"geometry":{"type":"Point","coordinates":[8.520355,47.476804]},"_id":"648c26c9e3f99b64ff16c197","title":"Oberglatt Camp", ...}';
</script>可以看到,JSON.stringify(campground)的输出结果是一个JSON字符串。然而,由于在EJS模板中,这个JSON字符串又被一对单引号 ' 包裹起来,导致在客户端JavaScript中,campground变量被赋值为一个字符串类型的值,而不是一个可以直接访问属性的JavaScript对象。
当JavaScript尝试执行 campground.geometry.coordinates 时,它实际上是在一个字符串上查找geometry属性。字符串没有geometry属性,因此campground.geometry会解析为undefined。随后,尝试访问undefined的coordinates属性便会抛出TypeError: Cannot read properties of undefined。
解决此问题的关键是确保 JSON.stringify(campground) 的输出在EJS模板中被直接作为JavaScript对象字面量进行赋值,而不是作为被引号包裹的字符串。
正确的EJS模板代码应移除 JSON.stringify(campground) 外部的单引号:
<script>
const mapToken = '<%=process.env.MAPBOX_TOKEN%>';
const campground = <%- JSON.stringify(campground) %>; // 正确示例
</script>解释:
1. show.ejs 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Campground Details</title>
<!-- Mapbox GL JS CSS -->
<link href="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css" rel="stylesheet">
<!-- 其他CSS链接 -->
</head>
<body>
<h1><%= campground.title %></h1>
<p><%= campground.location %></p>
<div id="map" style="width: 100%; height: 400px;"></div>
<!-- Mapbox GL JS JavaScript -->
<script src="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js"></script>
<script>
// 确保MAPBOX_TOKEN已在服务器端正确配置
const mapToken = '<%=process.env.MAPBOX_TOKEN%>';
// 关键修复:移除JSON.stringify外部的单引号
const campground = <%- JSON.stringify(campground) %>;
</script>
<script src="/path/to/your/showPageMap.js"></script>
<!-- 其他JavaScript文件 -->
</body>
</html>2. showPageMap.js 文件:
// 确保mapToken和campground变量已在show.ejs中正确定义和赋值
mapboxgl.accessToken = mapToken;
const map = new mapboxgl.Map({
container: 'map', // 地图容器的ID
style: 'mapbox://styles/mapbox/streets-v12', // Mapbox样式URL
center: campground.geometry.coordinates, // 使用正确解析的营地坐标
zoom: 8, // 初始缩放级别
});
// 添加导航控件
map.addControl(new mapboxgl.NavigationControl());
// 添加标记
new mapboxgl.Marker()
.setLngLat(campground.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({ offset: 25 })
.setHTML(`<h3>${campground.title}</h3><p>${campground.location}</p>`)
)
.addTo(map);// 在showPageMap.js中进行检查
if (campground && campground.geometry && campground.geometry.coordinates) {
mapboxgl.accessToken = mapToken;
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: campground.geometry.coordinates,
zoom: 8,
});
// ... 添加标记等
} else {
console.error("Campground data or coordinates are missing.");
// 可以显示一个替代信息或隐藏地图
}TypeError: Cannot read properties of undefined (reading 'coordinates') 在Mapbox与EJS集成中是一个常见的数据类型不匹配问题。通过理解EJS模板渲染机制和JavaScript数据类型,我们可以发现并纠正将JSON.stringify输出再次包裹在引号中的错误。移除EJS模板中JSON.stringify(campground)外部的额外引号,使得其直接作为JavaScript对象字面量被赋值,是解决此问题的根本方法。遵循正确的模板语法和数据传递原则,能够确保前端脚本正确解析后端数据,从而顺利实现Mapbox地图的各项功能。
以上就是解决EJS模板中Mapbox数据传递的TypeError问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号