解决TypeError: Cannot read properties of undefined (reading 'collection')错误
解决MongoDB任务管理CLI项目中的
TypeError: Cannot read properties of undefined (reading 'collection')错误 错误信息
const taskCollection = db.collection('tasks'); ^ TypeError: Cannot read properties of undefined (reading 'collection') at Command.<anonymous> (C:\Abc\xyz\Task-Manager-CLI-Project\index.js:50:31) at Command.listener [as _actionHandler] (C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:494:17) at C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:1296:65 at Command._chainOrCall (C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:1193:12) at Command._parseCommand (C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:1296:27) at C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:1082:27 at Command._chainOrCall (C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:1193:12) at Command._dispatchSubcommand (C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:1078:25) at Command._parseCommand (C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:1264:19) at Command.parse (C:\Abc\xyz\Task-Manager-CLI-Project\node_modules\commander\lib\command.js:910:10)
这是一个基于MongoDB和commander.js的简易任务管理CLI项目,已配置MongoDB连接但仍出现上述错误,无法正常执行list/add/delete命令。
项目代码文件
db.js
const { MongoClient } = require('mongodb'); const uri = 'mongodb://localhost:27017'; const client = new MongoClient(uri) let db; async function connect(){ try{ await client.connect(); db = client.db('task_manager_db'); console.log('Connected to the database'); } catch(err){ console.log('Error connecting to the database...', err); } } function getDB(){ return db; } module.exports = {connect, getDB};
index.js
const program = require('commander'); const {connect, getDB} = require('./db'); program .version('1.0.0') .description('Task Manager CLI') .action(connect()); // 列出所有任务的命令 --> list program .command('list') .description('列出所有任务') .action(async() => { const db = getDB(); const taskCollection = db.collection('tasks'); try{ const tasks = await taskCollection.find().toArray(); console.log("Listing all the tasks:"); tasks.forEach((task_) => { console.log(`- ${tasks.task_}`); }); }catch(err){ console.log("Error displaying tasks..."); } }); // 添加任务的命令 --> add <taskname> program .command('add <taskname>') .description('添加新任务') .action(async() => { const db = getDB(); const taskCollection = db.collection('tasks'); try{ const result = await taskCollection.insertOne({ taskname }); console.log(`New Task added: ${task} TaskID: ${result.insertedId}`); }catch(err){ console.log("Error adding task...", err); } }); // 删除任务的命令 --> delete <TaskId> program .command("delete <TaskId>") .description("删除任务") .action(async() => { const db = getDB(); const taskCollection = await db.collection('tasks'); try{ const result = await tasksCollection.deleteOne({ _id: new ObjectId(TaskId) }); console.log(`Deleted Task (ID: ${TaskId}`); }catch(err){ console.log("Error deleting a task...", err); } }); program.parse(process.argv);
已尝试的无效操作
- 修改MongoDB Compass连接名称为“Project1”并替换URI到db.js
- 将URI从
mongodb://localhost:27017改为mongodb://localhost:27018或mongodb://localhost:27017/Project1
问题根源与修复方案
1. 数据库连接时机错误
index.js中program.action(connect())直接调用了connect()函数,而非传递函数引用,且connect是异步函数,导致程序解析命令时数据库可能还未完成连接,getDB()返回undefined。
修复方法:
移除根命令的action,改为在program.parse之前先等待连接完成:
// 替换原来的program.action(connect()) async function init() { await connect(); program.parse(process.argv); } init();
2. 命令参数未正确接收
add命令的action未接收<taskname>参数,导致taskname变量未定义delete命令的action未接收<TaskId>参数,且未导入ObjectId
修复方法:
// 导入ObjectId const { ObjectId } = require('mongodb'); // 修改add命令的action program .command('add <taskname>') .description('添加新任务') .action(async(taskname) => { // 接收taskname参数 const db = getDB(); if (!db) { console.log("Database not connected"); return; } const taskCollection = db.collection('tasks'); try{ const result = await taskCollection.insertOne({ taskname }); console.log(`New Task added: ${taskname} TaskID: ${result.insertedId}`); // 修正变量名 }catch(err){ console.log("Error adding task...", err); } }); // 修改delete命令的action program .command("delete <TaskId>") .description("删除任务") .action(async(TaskId) => { // 接收TaskId参数 const db = getDB(); if (!db) { console.log("Database not connected"); return; } const taskCollection = db.collection('tasks'); // 移除多余的await try{ const result = await taskCollection.deleteOne({ _id: new ObjectId(TaskId) }); // 修正集合变量名 if (result.deletedCount === 0) { console.log(`No task found with ID: ${TaskId}`); return; } console.log(`Deleted Task (ID: ${TaskId})`); // 补全括号 }catch(err){ console.log("Error deleting a task...", err); } });
3. list命令中的遍历错误
list命令中tasks.forEach((task_) => { console.log(- ${tasks.task_}); })错误地访问了tasks.task_,应该是task_.taskname:
tasks.forEach((task_) => { console.log(`- ${task_.taskname} (ID: ${task_._id})`); });
4. 增加连接状态检查
在每个命令的action开头检查db是否存在,避免未连接时执行数据库操作:
const db = getDB(); if (!db) { console.log("Error: Database connection not established"); return; }
完成以上修改后,即可正常执行CLI命令,实现任务的增删查功能。
内容的提问来源于stack exchange,提问作者Ayush Singh
相关产品推荐
相关产品推荐

