Node.js操作MongoDB时create()函数无法创建数据是什么原因?
代码问题排查及修复方案
核心问题列表
- 未从请求体提取业务变量
代码中直接使用Email、PhoneNumber、FullName等变量,但是没有从req.body中解构赋值,所有变量均为undefined,导致读写数据库的条件和写入内容全部无效。 - 错误捕获逻辑完全失效
现有catch块的写法错误,内部定义的箭头函数永远不会执行,所有运行时错误被完全吞掉,所以看不到报错提示:
// 错误写法 catch { (err) => { console.log("error from New Step Form", err); res.json({ error: err }); }; }
- 存在未定义的变量引用
- 更新逻辑中使用的
SaveUserData._id没有定义来源,会触发引用错误 - 新建逻辑中使用的
hashedPassword没有做哈希处理也没有定义,会触发引用错误
- 更新逻辑中使用的
findOneAndUpdate配置缺失
默认情况下findOneAndUpdate只会执行更新,但不会返回更新后的文档,也不会自动触发字段校验,建议补充配置参数。- 冗余无效代码
const newformdata = new IITSchema({})定义后未被使用,属于冗余代码。
修复后的控制器代码
// 首先引入bcrypt做密码哈希,未安装可先执行npm i bcrypt const bcrypt = require('bcrypt') // 控制器逻辑 try { console.log(req.body) // 第一步:从req.body解构所有需要的变量 const { FullName, Email, password, Evidence, PhoneNumber, CollegeName, YearofGrad, GraduationDegree, Department, City, In_what_areas_do_you_need_our_help, targeted_companies, placement_time, interests, Others } = req.body let data = await IITSchema.findOne({ Email }) console.log(data) if (data) { // 不需要SaveUserData._id可直接删除该字段,有需要请自行补充变量定义 const updateFormData = await IITSchema.findOneAndUpdate( { Email }, { PhoneNumber, YearofGrad, FullName, Evidence, CollegeName, City, GraduationDegree, Department, placement_time, targeted_companies, interests, In_what_areas_do_you_need_our_help, Others, }, // 新增配置:返回更新后文档 + 执行字段校验 { new: true, runValidators: true } ); return res.status(200).json({ message: "update", data: updateFormData }); } else { // 密码哈希处理,盐轮数建议设置为10以上 const hashedPassword = await bcrypt.hash(password, 10) const newFormData = await IITSchema.create({ Email, password: hashedPassword, PhoneNumber, YearofGrad, FullName, Evidence, CollegeName, City, GraduationDegree, Department, placement_time, targeted_companies, interests, In_what_areas_do_you_need_our_help, Others, }); return res.status(200).json({ message: "create", data: newFormData }); } } catch (err) { // 直接处理错误,不要套箭头函数 console.log("error from New Step Form", err); res.status(500).json({ error: err.message }); }
其他注意事项
- 模型中
YearofGrad字段定义为String类型,前端传入的是数字类型,Mongoose会自动转换,不影响写入,也可以根据业务需要调整字段类型为Number - 前端请求最好补充
catch块捕获网络或接口报错:
await fetch(BASE_URL + "/iitbfform", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newData), }) .then((res) => res.json()) .then((data) => { console.log("Response from firstForm", data); }) .catch(err => { console.error("请求出错", err) })
- 确认Mongoose数据库连接正常,集合名是否符合预期:默认Mongoose会把模型名转为小写复数作为集合名,也就是
iitbombays,如果你的集合名不是这个,可以在model的第三个参数指定集合名:mongoose.model("iitbombay", IITSchema, "你实际的集合名")
内容的提问来源于stack exchange,提问作者Mohammed Khan
相关产品推荐
相关产品推荐

