如何修复Express+Handlebars中「TypeError: Cannot read property 0 of undefined」错误?
问题分析与解决方案
你遇到的问题核心是异步Promise的执行顺序问题,导致渲染模板时row还未被正确赋值,所以访问row[0]会抛出Cannot read property 0 of undefined错误。
为什么会出现这个问题?
你的代码里q = chuyenmuc.singel(id)和p = baivietModel.allByCat(id)是两个独立的Promise,它们的执行是并行的。你在p.then的回调里直接使用row,但这时候q.then的回调可能还没执行(Promise的异步特性),row仍然是初始声明的undefined,自然无法访问row[0]。
修复方案
使用Promise.all()来同时等待两个Promise完成,确保渲染模板时,baiviet和CM的数据都已经准备好。修改后的路由代码如下:
router.get('/:id/baiviet', (req, res) => { var id = req.params.id; // 同时发起两个异步请求,等待所有请求完成 Promise.all([ baivietModel.allByCat(id), chuyenmuc.singel(id) ]).then(([baivietRows, cmRows]) => { // 处理导航激活状态 for (const cm of res.locals.lcChuyenmuc) { if (cm.ID == +id) { cm.isActive = true; } } // 此时cmRows已确定有值,直接取第一个元素传入模板 res.render('vwBaiviet/byCat', { baiviet: baivietRows, CM: cmRows[0] }); }).catch(err => { console.log(err); }); });
额外优化建议
- 模板里的
{{this.CM.Name}}可以简化为{{CM.Name}},因为模板上下文可以直接访问传入的变量。 - 为了避免
cmRows为空数组的情况(比如分类不存在),建议在模板里做容错处理:{{#if CM}} {{CM.Name}} {{else}} 暂无分类信息 {{/if}}
内容的提问来源于stack exchange,提问作者Nhất Hàn
相关产品推荐
相关产品推荐

