JS运行Mongoose脚本为何报读取null的addresses属性TypeError
问题描述
运行JS代码连接Mongoose操作MongoDB时抛出类型错误,执行命令及报错信息如下:
$ node user.js mongo connection is open D:\web development practice\mongoose_relationship\Models\user.js:44 u.addresses.push({ ^ TypeError: Cannot read properties of null (reading 'addresses') at addAddress (D:\web development practice\mongoose_relationship\Models\user.js:44:7)
对应业务代码如下:
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/relationshipDemo', { useNewUrlParser: true }) .then(() => { console.log("mongo connection is open") }) .catch(e => { console.log("oh no mongoose connection error"); console.log(e); }) const userSchema = new mongoose.Schema({ first: String, last: String, addresses: [{ _id: { id: false }, street: String, city: String, state: String, country: String }] }) const User = mongoose.model('User', userSchema); const makeUser = async () => { const u = new User({ first: 'Harry', last: 'Potter' }) u.addresses.push({ street: 'baker street', city: 'london', state: 'london', country: 'uk' }) await User.deleteMany(); const res = await u.save(); console.log(res); } const addAddress = async (id) => { const u = await User.findById(id); u.addresses.push({ street: 'florida street', city: 'new york', state: 'new york', country: 'usa', }) const res = await u.save(); console.log(res); } addAddress('62ceae58cbb52805b8150ce9');
报错原因
报错核心是u.addresses.push这行里的u为null,即User.findById(id)没有查到匹配id的用户文档,直接返回了空值,共有3个相关问题:
- 代码末尾只调用了
addAddress,从未执行makeUser()方法,数据库里本身没有任何用户数据,自然查不到对应id的记录 - 就算手动执行过
makeUser(),Mongoose每次新建文档都会生成随机的唯一_id,硬编码传入的id62ceae58cbb52805b8150ce9和实际生成的用户id不匹配,查询结果必然为空 - 存在schema写法错误:子文档配置禁用
_id的正确写法为_id: false,原有写法_id: { id: false }是无效配置,不会生效
修复方法
- 数据库查询后必须增加空值判断,避免查不到数据时直接操作属性抛出异常
- 不要硬编码用户id,调整执行逻辑:先创建用户拿到生成的真实_id,再用这个id调用添加地址的方法
- 修正schema中子文档禁用_id的配置写法
修复后的可运行代码:
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/relationshipDemo', { useNewUrlParser: true }) .then(() => { console.log("mongo connection is open") }) .catch(e => { console.log("oh no mongoose connection error"); console.log(e); }) const userSchema = new mongoose.Schema({ first: String, last: String, addresses: [{ _id: false, // 修正子文档_id禁用写法 street: String, city: String, state: String, country: String }] }) const User = mongoose.model('User', userSchema); const makeUser = async () => { await User.deleteMany(); const u = new User({ first: 'Harry', last: 'Potter' }) u.addresses.push({ street: 'baker street', city: 'london', state: 'london', country: 'uk' }) const res = await u.save(); console.log('创建用户成功:', res); return res; // 返回创建好的用户文档,获取真实_id } const addAddress = async (id) => { const u = await User.findById(id); // 增加空值判断 if (!u) { console.log('未找到对应用户'); return; } u.addresses.push({ street: 'florida street', city: 'new york', state: 'new york', country: 'usa', }) const res = await u.save(); console.log('添加地址成功:', res); } // 调整执行顺序,先创建用户再拿对应id添加地址 const run = async () => { const user = await makeUser(); await addAddress(user._id); } run();
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

