MongoDB报错TypeError: Cannot read properties of null (reading 'collection')求助
问题:Node.js连接MongoDB时出现
TypeError: Cannot read properties of null (reading 'collection') 我在使用Node.js连接MongoDB时遇到错误:TypeError: Cannot read properties of null (reading 'collection'),问题源于indexHelpers.js中调用db.get().collection()时,db.get()返回null,打印console.log(db.get())结果确实是null,无法获取数据库实例。
相关代码
indexHelpers.js
var db = require("../config/connection"); var collections = require("../config/collections"); var ObjectId = require("mongodb").ObjectId; module.exports = { addPerson: (personDetails) => { return new Promise((resolve, reject) => { db.get().collection(collections.USER_DETAILS) .insertOne(personDetails) .then((details) => { resolve(details); }); }); }, };
connection.js
const mongoClient = require("mongodb").MongoClient; const state = { db: null, }; module.exports.connect = function (done) { const url = "mongodb://localhost://27017"; const dbname = "CMS"; mongoClient.connect(url, { useUnifiedTopology: true }, (err, data) => { if (err) return done(err); state.db = data.db(dbname); }); done(); }; module.exports.get = function () { return state.db; };
app.js(数据库连接相关部分)
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var db = require("./config/connection"); var indexRouter = require('./routes/index'); var hbs = require("express-handlebars"); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hbs'); app.engine( "hbs", hbs.engine({ extname: "hbs", defaultLayout: "layout", layoutsDir: __dirname + "/views/" }) ); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); db.connect((err) => { if (err) console.log("connection error" + err); else console.log("--------Database Connected--------"); }); app.use('/', indexRouter); // 错误处理部分省略... module.exports = app;
问题排查与修复
1. MongoDB连接URL格式错误
connection.js中的URL写成了"mongodb://localhost://27017",多了一个斜杠,导致连接失败,state.db始终为null。正确的URL格式应为"mongodb://localhost:27017"或"mongodb://127.0.0.1:27017"。
2. 异步连接逻辑错误
connection.js的connect函数中,done()被提前调用了。mongoClient.connect是异步操作,在连接完成前就执行done(),会导致app.js中误以为连接已完成,但此时state.db还未被赋值。需将done()移到connect的回调内部。
3. 路由挂载时机错误
app.js中在数据库连接完成前就挂载了路由,当请求进来时,数据库可能还未连接成功,导致db.get()返回null。需将路由挂载放在db.connect的成功回调中。
修复后的代码
修复后的connection.js
const mongoClient = require("mongodb").MongoClient; const state = { db: null, }; module.exports.connect = function (done) { // 修复URL格式 const url = "mongodb://localhost:27017"; const dbname = "CMS"; mongoClient.connect(url, { useUnifiedTopology: true }, (err, data) => { if (err) return done(err); state.db = data.db(dbname); // 连接成功后再调用done() done(); }); }; module.exports.get = function () { return state.db; };
修复后的app.js(关键部分)
// ... 其他代码保持不变 db.connect((err) => { if (err) console.log("connection error" + err); else { console.log("--------Database Connected--------"); // 数据库连接成功后再挂载路由 app.use('/', indexRouter); // 确保服务器在连接完成后启动(如果服务器启动逻辑在bin/www,需同步调整) const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); } }); // 注释掉原来提前挂载的路由 // app.use('/', indexRouter);
优化后的indexHelpers.js(可选)
无需手动包装Promise,直接返回insertOne的Promise即可:
var db = require("../config/connection"); var collections = require("../config/collections"); var ObjectId = require("mongodb").ObjectId; module.exports = { addPerson: (personDetails) => { return db.get().collection(collections.USER_DETAILS).insertOne(personDetails); }, };
内容的提问来源于stack exchange,提问作者Adarsh S
相关产品推荐
相关产品推荐

