Express全局变量结合Handlebars渲染时出现_id读取错误排查
解决Handlebars自定义Helper调用时的TypeError问题
问题场景
在Express项目中,通过app.use设置全局变量res.locals.user存储登录用户信息;在Handlebars的index.hbs模板中调用自定义helper函数updateIcon,传入帖子所属用户、全局登录用户及帖子ID,期望仅登录用户自身的帖子显示编辑图标,但运行时触发TypeError: Cannot read properties of undefined (reading '_id')错误。
相关代码
app.js 全局变量设置
// Set global variable app.use(function (req, res, next) { res.locals.user = req.user || null next() })
index.hbs 模板代码
<h1>All posts</h1> <div class="row"> {{#each posts}} <div class="col s12 m4"> <div class="card"> <div class="card-image"> {{{updateIcon user ../user _id}}} </div> <div class="card-content center-align"> <h5>{{title}}</h5> <p>{{body)}}</p> <br> <div class="chip"> <img src="{{user.image}}" alt=""> <a href="/stories/user/{{user._id}}">{{user.displayName}}</a> </div> </div> <div class="card-action center-align"> <a href="/stories/{{_id}}" class="btn grey">Read More</a> </div> </div> </div> {{else}} <p>No posts</p> {{/each}} </div>
hbs.js 自定义Helper函数
updateIcon: function (postUser, loggedInUser, postId, floating = true) { console.log(`${postUser._id} ${loggedInUser._id}`) if (postUser._id.toString() === loggedInUser._id.toString()) { if (floating) { return `<a href="/posts/update/${postId}" class="btn-floating halfway-fab blue"><i class="fas fa-edit fa-small"></i></a>` } else { return `<a href="/posts/update/${postId}"><i class="fas fa-edit"></i></a>` } } else { return '' } },
错误原因分析
- 未登录时全局用户为null:当用户未登录时,
res.locals.user被设为null,此时模板中传入的../user为null,在helper中访问loggedInUser._id会触发错误。 - 帖子用户字段可能缺失:部分帖子数据的
user字段可能不存在或为undefined,访问postUser._id也会引发错误。 - 模板语法错误:模板中
{{body)}}使用了错误的右括号,虽不直接导致当前TypeError,但会影响模板渲染。
解决方案
1. 给Helper添加空值检查
修改updateIcon函数,先确保postUser和loggedInUser存在且包含_id属性,再执行后续逻辑:
updateIcon: function (postUser, loggedInUser, postId, floating = true) { // 先校验参数有效性 if (!postUser || !loggedInUser || !postUser._id || !loggedInUser._id) { return ''; } if (postUser._id.toString() === loggedInUser._id.toString()) { if (floating) { return `<a href="/posts/update/${postId}" class="btn-floating halfway-fab blue"><i class="fas fa-edit fa-small"></i></a>`; } else { return `<a href="/posts/update/${postId}"><i class="fas fa-edit"></i></a>`; } } else { return ''; } },
2. 修正模板语法错误
将index.hbs中的{{body)}}改为{{body}}:
<p>{{body}}</p>
3. 模板中提前判断登录状态(可选优化)
在调用helper前先判断全局用户是否存在,减少无效执行:
<div class="card-image"> {{#if ../user}} {{{updateIcon user ../user _id}}} {{/if}} </div>
效果说明
修改后,无论用户是否登录,或者帖子用户字段是否缺失,都不会触发TypeError;仅当登录用户是帖子作者时,才会显示编辑图标。
内容的提问来源于stack exchange,提问作者Jyotirmoy
相关产品推荐
相关产品推荐

