大家好,我是梅巴哥er,本篇介绍关于Cannot read property '_id' of undefined这个报错的解决。
俗话说,一杯茶,一支烟,一个BUG改一天。
必须要写个博客纪念下,昨天搞到凌晨五点,终于解决了这个问题。主要还是懂的太少,写的项目不多,遇到问题,只能一步步查原因,一点点的搜索,过程非常非常慢,非常非常的艰难。而且这个报错都搜不到解决办法,只能自己摸索。
看前提示:这里面注释掉的代码,都是我在测试时用来验证错误出在哪里的代码。为方便大家理解这个解决问题的思路,注释代码我就保留了。
先看下报错原因: 我分别在cookie和响应数据data中,用到了user._id,本来想着这样用,也没什么错,毕竟保存user的时候,会自动生成一个_id,看似很合理,但是为啥又报错了呢? (附代码)
// 注册的路由 router.post('/register', function(req, res) { // 读取请求参数数据 const { username, password, type } = req.body // console.log(id) // const _id = id // console.log(typeof(_id)) // console.log(req.body) // console.log(req.body.username) // console.log({ username }) // console.log(username) // console.log({ username, password, type }) // 处理 // 1,判断 看用户是否存在 UserModel.findOne( { username }, function(err, user) { // console.log(user) // console.log(username) // console.log(user.username) if (user) { // user已存在,user值为true // 返回提示错误信息 res.send({ code: 1, msg: '此用户已存在' }) // console.log(user) } else { // user不存在 // console.log(user) // 保存注册的用户数据 new UserModel({ username, password: md5(password), type }).save(function(err, user) { // console.log(user) // 在发送响应数据之前,生成一个cookie(userid: user._id), // 并交给浏览器保存 // 参数maxAge单位是毫秒,表示cookie存活的时间。 // 1000*60*60*24 是一天 res.cookie('userid', user._id , { maxAge: 1000*60*60*24 }) // 响应数据中,不要携带密码 const data = { _id: user._id , username, type } res.send({ code: 0, data }) // console.log(err, user) // res.send(user) }) } }) // 返回响应数据 })问题解决: 经多次验证和查找资料,确实出在这个_id的应用上。下面逐条说明错误原因和解决思路。
在往数据库中保存数据时,_id确实会自动生成,但是他是ObjectId类型的数据做响应时,我们会从后台拿到一个id,这个id是json类型的数据。_id和id根本不是同一个类型的,当我们把id拿给_id用的时候,就会报错思路:我们把从后台拿到的json类型的id转换成ObjectId类型的数据不就可以了吗?于是: 先做个引入:const ObjectId = require('mongodb').ObjectId再把从后台拿到的id做个转换: const id = ObjectId(req.body.id)这时候的id就可以给_id用了。俩数据的类型一致了。即{ _id: id}。附正确完整代码:
var express = require('express'); var router = express.Router(); // UserModel在models.js文件里已经暴露出来了,要拿到这里用,所以要先引入 const UserModel = require('../db/models').UserModel // console.log(UserModel) // 引入密码加密的包 const md5 = require('blueimp-md5') // 如果没有这里的引入,还有后面id的定义,会报错: // TypeError: Cannot read property '_id' of undefined // 解决办法就是,先引入,再定义id,最后把user._id换成id即可。 const ObjectId = require('mongodb').ObjectId /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); // 测试: 定义一个路由,实现用户注册 /* a) path为 /register b) 请求方式为post c) 接收username和password参数 d) admin是已注册用户 e) 注册成功,返回: { code:0, data: { _id: 'abc', username: 'xxx', password: '123' } } f) 注册失败,返回: {code: 1, msg: '此用户已存在'} */ // router.post('/register', (req, res) => { // /* 1,获取请求参数 // 2,处理 // 3,返回响应数据 */ // const {username, password} = req.body // if (username === 'admin') { // res.send({code: 1, msg: '此用户已存在'}) // } else { // res.send({ code: 0, data: { id: 'abc', username, password } }) // } // }) // 注册的路由 router.post('/register', function(req, res) { // 读取请求参数数据 // 此时的id才是后台传过来的id,才能与数据库对照 const id = ObjectId(req.body.id) const { username, password, type } = req.body // console.log(id) // const _id = id // console.log(typeof(_id)) // console.log(req.body) // console.log(req.body.username) // console.log({ username }) // console.log(username) // console.log({ username, password, type }) // 处理 // 1,判断 看用户是否存在 UserModel.findOne( { username }, function(err, user) { // console.log(user) // console.log(username) // console.log(user.username) if (user) { // user已存在,user值为true // 返回提示错误信息 res.send({ code: 1, msg: '此用户已存在' }) // console.log(user) } else { // user不存在 // console.log(user) // 保存注册的用户数据 new UserModel({ username, password: md5(password), type }).save(function(err, user) { // console.log(user) // 在发送响应数据之前,生成一个cookie(userid: user._id), // 并交给浏览器保存 // 参数maxAge单位是毫秒,表示cookie存活的时间。 // 1000*60*60*24 是一天 res.cookie('userid', id/* user._id */, { maxAge: 1000*60*60*24 }) // 响应数据中,不要携带密码 const data = { _id: id/* user._id */, username, type } res.send({ code: 0, data }) // console.log(err, user) // res.send(user) }) } }) // 返回响应数据 }) // const userModel = new UserModel({ // username: 'ming', // password: 233, // type: 'dashen' // }) // userModel.save((err, user) => { // console.log(err, 'user is', user) // }) // 登录的路由 module.exports = router;成功解决,保存测试数据附图如下:
