2

I'm having trouble getting data from MongoDB using mongoose schemas with express. I first tested with just mongoose in a single file (mongoosetest.js) and it works fine. But when I start dividing it all up with express routes and config files, things start to break. I'm sure it's something simple, but I've spent the last 3 hours googling and trying to figure out what I'm doing wrong and can't find anything that matches my process enough to compare.

mongoosetest.js (this works fine, but not for my application)

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/meanstack');

var db = mongoose.connection;

var userSchema = mongoose.Schema({
  name: String
}, {collection: 'users'});

var User = mongoose.model('User', userSchema);

User.find(function(err, users) {
  console.log(users);
});

These files are where I'm having issues. I'm sure it's something silly, probably a direct result of using external files, exports, and requires. My server.js file just starts up and configures express. I also have a routing file and a db config file.

routing file (allRoutes.js)

var express = require('express');
var router = express.Router();
var db = require('../config/db');
var User = db.User();

// routes
router.get('/user/list', function(req, res) {
  User.find(function(err, users) {
    console.log(users);
  });
});

// catch-all route
router.get('*', function(req, res) {
  res.sendfile('./public/index.html');
});

module.exports = router;

dbconfig file (db.js)

var mongoose = require('mongoose');
var dbHost = 'localhost';
var dbName = 'meanstack';
var db = mongoose.createConnection(dbHost, dbName);
var Schema = mongoose.Schema, ObjectId = Schema.ObjectId;

db.once('open', function callback() {
  console.log('connected');
});

// schemas
var User = new Schema({
  name    : String
}, {collection: 'users'});

// models
mongoose.model('User', User);
var User = mongoose.model('User');

//exports
module.exports.User = User;

I receive the following error when I browse to localhost:3000/user/list

TypeError: Object { _id: 5398bed35473f98c494168a3 } has no method 'find' at 
Object.module.exports [as handle] (C:\...\routes\allRoutes.js:8:8) at next_layer 
(C:\...\node_modules\express\lib\router\route.js:103:13) at Route.dispatch 
(C:\...\node_modules\express\lib\router\route.js:107:5) at 
C:\...\node_modules\express\lib\router\index.js:213:24 at Function.proto.process_params 
(C:\...\node_modules\express\lib\router\index.js:284:12) at next 
(C:\...\node_modules\express\lib\router\index.js:207:19) at Function.proto.handle 
(C:\...\node_modules\express\lib\router\index.js:154:3) at Layer.router 
(C:\...\node_modules\express\lib\router\index.js:24:12) at trim_prefix 
(C:\...\node_modules\express\lib\router\index.js:255:15) at 
C:\...\node_modules\express\lib\router\index.js:216:9

Like I said, it's probably something silly that I'm messing up with trying to organize my code since my single file (mongoosetest.js) works as expected. Thanks.

2 Answers 2

2

Why are you calling User?

var User = db.User();

Try

var User = db.User;

Calling it is allowed, since it is a constructor, but it probably doesn't return anything useful (the error message implies that it is constructing an empty User object, I think).

Sign up to request clarification or add additional context in comments.

3 Comments

var User = db.User; results in a long hang and timeout. db.User(); results in an instant error.
@sdouble But is it console.loging during the "long hang"? You're never sending a response, so the hanging is expected behavior.
No, there's nothing. I have also added another console.log('test') right before the c.log(users) and that doesn't echo out either. Once it hits .find, it's toast. I have no problem at all if I do it all in a single file, so I think it's something to do with how I'm referencing.
1

I figured it out.

Apparently, db.once('open'... isn't the same as mongoose.connect. Switched my dbconfig.js file to the following and all is well (using var User = db.User; in allRoutes.js as Aaron Dufour suggested).

var mongoose = require('mongoose');
var Schema = mongoose.Schema, ObjectId = Schema.ObjectId;

mongoose.connect('mongodb://localhost/meanstack');

// schemas
var User = new Schema({
  name    : String
}, {collection: 'users'});

// models
mongoose.model('User', User);

//exports
module.exports.User = mongoose.model('User');

EDIT: Can't mark this as the answer for 2 days.

4 Comments

It's not so much db.once vs mongoose.connect, but mongoose.createConnection vs mongoose.connect. You should really only need to use mongoose.createConnection if you need multiple connections open. When you use mongoose.createConnection it will create multiple, and you have to specify which you use in the query calls. Because you weren't specifying which one to use, the query hung. Switching to mongoose.connect has only one connection, so the query succeeds.
For more information on this see mongoosejs.com/docs/connections.html (or this stack overflow answer is useful as well: stackoverflow.com/a/22838614)
@dylants thanks, that helped me quite a bit. I changed my original code to db.model instead of mongoose.model and it worked as well. It makes a lot more sense to me now. mongoose.connection opens a default connection for mongoose, but mongoose.createConnection opens and returns a connection. What I seem to have been doing is creating/opening a new connection but trying to work off of the default connection that I never connected.
Right, exactly :) I don't know why mongoose doesn't use the default connection (connections[0]) when you call createConnection if it hasn't been established/created yet. They seem to instead expect you to use connect first and then createConnection for additional connections.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.