Node.js中出现Cannot read property 'courses' of undefined错误求助
看起来你遇到的这个错误,核心原因是你尝试访问一个undefined对象的courses属性,结合你的代码来看,主要有几个可能的点,我来一步步帮你排查和解决:
1. 最可能的原因:Subject.find()未找到匹配的文档,导致theSubject[0]为undefined
你的POST路由里用了Subject.find({name: req.params.subject}),这个方法返回的是一个数组。如果数据库里没有名字匹配req.params.subject的Subject文档,theSubject就是一个空数组,theSubject[0]自然就是undefined,这时候执行theSubject[0].courses.push()就会抛出你看到的错误。
修复方案:
改用Subject.findOne()代替Subject.find(),因为你是根据name查找单个主题,findOne直接返回单个文档(找不到就是null),更符合你的需求,同时增加存在性检查:
//POST ROUTE FOR COURSES app.post("/:subject/courses", function (req, res) { // 改用findOne查找单个文档 Subject.findOne({name: req.params.subject}, function (err, theSubject) { if (err) { res.redirect("/") console.log(err) } else { // 先检查是否找到对应的主题 if (!theSubject) { console.log("找不到对应的主题:", req.params.subject); return res.redirect("/"); } Course.create(req.body.courses, function (err, createdCourse) { if (err) { console.log(err) } else { console.log("===========theSubject==========="); console.log(theSubject); console.log("===========req.body.courses==========="); console.log(req.body.courses); console.log("===========createdCourse==========="); console.log(createdCourse); console.log("==========="); theSubject.courses.push(createdCourse); // 给save方法添加回调处理保存错误 theSubject.save(function(saveErr) { if (saveErr) { console.log(saveErr); return res.redirect("/" + req.params.subject); } // 重定向到正确的主题页面 res.redirect("/" + req.params.subject) }); } }) } }) })
2. 第二个可能:未配置表单数据解析中间件,导致req.body.courses为undefined
如果你的Express应用没有配置express.urlencoded中间件,表单提交的数据不会被解析,req.body会是空对象,这时候req.body.courses就是undefined,也可能引发类似错误。
修复方案:
在你的Express应用入口文件里,在定义路由之前添加以下中间件配置:
app.use(express.urlencoded({ extended: true }));
3. 额外的小问题:重定向路径错误
你的POST路由最后用了res.redirect("/:subject"),这里的:subject是路由的占位符,不是实际的参数值,应该用req.params.subject拼接正确的路径:
res.redirect("/" + req.params.subject);
4. 补充优化:GET路由的冗余错误处理简化
你的GET路由里有重复的if (err)判断,可以简化让代码更清晰:
app.get("/:subject", function (req, res) { Subject.findOne({name: req.params.subject}).populate("courses").exec(function (err, foundSubject) { if (err) { console.log(err); return res.redirect("/"); } // 检查是否找到主题 if (!foundSubject) { console.log("找不到主题:", req.params.subject); return res.redirect("/"); } console.log(foundSubject); console.log(foundSubject.courses); res.render("template.ejs", {subjects: foundSubject, courses: foundSubject.courses}); }) })
这样调整之后,应该就能解决你遇到的错误了,测试前记得确认数据库里存在对应name的Subject文档哦!
内容的提问来源于stack exchange,提问作者ChrisLEE

