You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js初学者遇Cannot read property 'collection' of undefined错误求助

Hey there, Leon! Let’s break down that Cannot read property 'collection' of undefined error you’re hitting with your Node.js todo app—it’s almost always tied to how your MongoDB/Mongoose connection or data models are set up. Let’s walk through the most common issues and fixes, focusing on your key files:

1. First: Verify Your MongoDB Connection in app.js

This is the #1 culprit for this error. If your app tries to access a database collection before the connection is fully established, Mongoose will return undefined for the collection reference.

Correct Connection Flow:

const express = require('express');
const mongoose = require('mongoose');
const app = express();

// 1. Connect to MongoDB FIRST, before loading models/routes
mongoose.connect('mongodb://localhost:27017/todoDB', { 
  useNewUrlParser: true, 
  useUnifiedTopology: true 
})
.then(() => console.log('Successfully connected to MongoDB!'))
.catch(err => console.error('MongoDB connection failed:', err));

// 2. THEN load your models and routes
const Todo = require('./models/Todo'); // Make sure this path is correct!
const todoRoutes = require('./routes/Todo');

// Middleware for parsing form data (critical for POST requests)
app.use(express.urlencoded({ extended: true }));
app.set('view engine', 'handlebars');

// Mount routes
app.use('/', todoRoutes);

app.listen(3000, () => console.log('Server running on port 3000'));

What to Avoid:

Never load your models or routes before establishing the MongoDB connection—this is the most common reason for the collection undefined error.

2. Check Your Todo Model Definition

Chances are you’re missing a proper Mongoose model (or it’s incorrectly exported). Create a models/Todo.js file if you haven’t already, with this structure:

const mongoose = require('mongoose');

const todoSchema = new mongoose.Schema({
  title: { type: String, required: true },
  completed: { type: Boolean, default: false }
});

// Export the model (this is how routes will access the collection)
module.exports = mongoose.model('Todo', todoSchema);

If this file is missing, or the export is wrong, any attempt to access Todo.collection will throw your error.

3. Fix Your routes/Todo.js Logic

Make sure you’re correctly importing the model and using Mongoose’s built-in methods (instead of directly accessing collection, which is unnecessary here):

const express = require('express');
const router = express.Router();
const Todo = require('../models/Todo'); // Double-check this file path!

// GET all todos
router.get('/', async (req, res) => {
  try {
    const todos = await Todo.find(); // Use Mongoose's find() instead of collection
    res.render('index', { todos });
  } catch (err) {
    res.status(500).send(`Error fetching todos: ${err.message}`);
  }
});

// POST a new todo
router.post('/', async (req, res) => {
  try {
    const newTodo = new Todo({
      title: req.body.title
      // completed defaults to false, per our model
    });
    await newTodo.save();
    res.redirect('/'); // Redirect back to the todo list
  } catch (err) {
    res.status(500).send(`Error adding todo: ${err.message}`);
  }
});

module.exports = router;

If the path to ../models/Todo is wrong (e.g., ./models/Todo if your routes folder is nested differently), Todo will be undefined, triggering the error.

4. Quick Check for views/index.handlebars

Ensure your template is set up to receive and display the todos data correctly:

<h1>My Todo List</h1>

<!-- Add Todo Form -->
<form action="/" method="POST">
  <input type="text" name="title" placeholder="Enter a new todo..." required>
  <button type="submit">Add Todo</button>
</form>

<!-- Todo List -->
<ul>
  {{#each todos}}
    <li>
      {{title}} 
      <span>({{completed ? 'Done' : 'Not Done'}})</span>
    </li>
  {{else}}
    <li>No todos yet! Add one above.</li>
  {{/each}}
</ul>

This won’t fix the collection error directly, but it ensures your GET/POST requests render data correctly once the backend is fixed.

Final Troubleshooting Steps
  1. Run your app and check the console: If you see a MongoDB connection error, fix that first (make sure MongoDB is running locally on port 27017, or update your connection string).
  2. Verify all file paths: A typo in require('../models/Todo') is easy to miss and will break everything.
  3. Avoid direct collection access: Mongoose’s methods like find(), save(), etc., handle collection interactions safely—you rarely need to call collection directly.

内容的提问来源于stack exchange,提问作者Leon Bogod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:54:36