提交表单时遇Cannot read properties of null错误,无法存储数据到数据库
错误原因及修复方案
核心问题:异步操作顺序错误
你的错误是因为数据库连接还未完成时,就调用了db.get()获取数据库实例,导致state.db还是null,进而访问null.collection时报错。
看connection.js里的connect函数:mongoClient.connect是异步操作,但你在调用它之后立刻执行了done(),这时候回调函数里的state.db=data.db(dbname)还没执行,state.db仍然是初始的null。
修复步骤
1. 修正connection.js的异步逻辑
把done()移到mongoClient.connect的回调函数内部,确保只有当数据库连接成功(或失败)后才执行回调:
const mongoClient=require('mongodb').MongoClient const state={ db:null } module.exports.connect=function (done){ const url='mongodb://localhost:27017/' const dbname='shopping' mongoClient.connect(url,(err,data)=>{ if(err) return done(err) state.db=data.db(dbname) done() // 移到这里,确保连接完成后再通知 }) } module.exports.get=()=>state.db
2. 确保应用启动时先完成数据库连接
在你的主入口文件(比如app.js)中,要先调用connect函数,等待连接成功后再启动服务器或处理请求:
const db = require('./config/connection'); const express = require('express'); const app = express(); // 先连接数据库,再启动服务器 db.connect((err) => { if(err) console.log('数据库连接失败:', err); else { console.log('数据库连接成功'); app.listen(3000, () => { console.log('服务器启动在3000端口'); }); } });
3. 可选:优化product-helpers的异步写法
你当前用了.then但搭配了回调函数,可以统一成Promise风格或者async/await,让代码更清晰:
var db=require('../config/connection') module.exports={ addProduct:(product)=>{ console.log(product) return db.get().collection('product').insertOne(product) } }
然后在调用的地方用async/await:
// 比如在路由处理中 app.post('/add-product', async (req, res) => { try { await productHelpers.addProduct(req.body); res.redirect('/'); } catch(err) { console.log(err); res.status(500).send('添加产品失败'); } });
验证修复
完成以上修改后,重启应用,提交表单时应该能正常将数据存入MongoDB的shopping.product集合了。
内容的提问来源于stack exchange,提问作者Shahun
相关产品推荐
相关产品推荐

