Reputation: 161
Good afternoon,
I recently started working with Node.js + Express + MongoDB. I set up a simple app containing :
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, mongoose = require('mongoose')
, models = require('./models')
, Document
, db;
// lots of conf ...
models.defineModels(mongoose, function() {
app.Document = Document = mongoose.model('Document');
db = mongoose.connect(app.set('db-uri'));
})
// Routes
app.get('/', routes.home);
app.get('/documents.:format?', routes.list);
// classical end of app.js
I also have a corresponding 'index.js' file within a 'routes' folder, containing:
exports.home = function(req, res){
res.render('index', { title: 'Indx' })
};
exports.list = function(req, res){
Document.find().all(function(documents) {
switch (req.params.format) {
case 'json':
res.send(documents.map(function(d) {
return d.__doc;
}));
break;
default:
res.render('index', { title: 'Indx' });
}
});
};
The routing part is OK, meaning that when I point my browser to localhost:3000, I see the (Jade-template generated) 'index' view. When I point to localhost:3000/documents, the routing works OK, and the code is trying to serve the 'list' part of my 'index.js' route. However, I was hoping that the 'Document' mongoose model I created in the main app would be recognized within 'index.js', but this is clearly not the case as I keep getting the following error :
Express
500 ReferenceError: Document is not defined
at C:\PERSO\DEV\indxjs\routes\index.js:23:2
at callbacks (C:\PERSO\DEV\indxjs\node_modules\express\lib\router\index.js:272:11)
at param (C:\PERSO\DEV\indxjs\node_modules\express\lib\router\index.js:246:11)
at param (C:\PERSO\DEV\indxjs\node_modules\express\lib\router\index.js:243:11)
at pass (C:\PERSO\DEV\indxjs\node_modules\express\lib\router\index.js:253:5)
at Router._dispatch (C:\PERSO\DEV\indxjs\node_modules\express\lib\router\index.js:280:4)
at Object.handle (C:\PERSO\DEV\indxjs\node_modules\express\lib\router\index.js:45:10)
at next (C:\PERSO\DEV\indxjs\node_modules\express\node_modules\connect\lib\http.js:204:15)
at Object.methodOverride [as handle] (C:\PERSO\DEV\indxjs\node_modules\express\node_modules\connect\lib\middleware\methodOverride.js:35:5)
at next (C:\PERSO\DEV\indxjs\node_modules\express\node_modules\connect\lib\http.js:204:15)
I could obviously define my routing from within the 'app.js' with something like :
app.get('/documents.:format?', loadUser, function(req, res) {
// ...
}
But can anyone see a way of talking with mongoose while retaining the elegant './routes/index.js' separation from the 'app.js' ?
Thanks a lot
EDIT : following kind answer from Wes, I added the following code to 'index.js':
var Document;
function defineRoutes(mongoose, fn) {
Document = mongoose.model('Document');
fn();
}
exports.defineRoutes = defineRoutes;
// then the same as in initial post
And I enclosed the routing definitions within this function in 'app.js' :
routes.defineRoutes(mongoose, function() {
app.get('/', routes.home);
app.get('/documents.:format?', routes.list);
})
Everything is ok when I point to localhost:3000, but when I point to /documents, the browser keeps loading, loading ...
Upvotes: 3
Views: 5079
Reputation: 161
Thanks to Wes Johnson, I found my way out. I was blindly following a dated tutorial, which used deprecated methods from MongoDb. Below is the code snippet I finally used to implement the 'list documents' feature:
exports.list = function(req, res){
Document.find({},function(err, documents) {
switch (req.params.format) {
case 'json':
res.send(documents.map(function(d) {
return d.toObject();
}));
break;
default:
res.render('index', { title: 'Indx' });
}
});
};
Once again, thanks Wes !
Upvotes: 2
Reputation: 3101
Node modules are self-contained in terms of variable scope. Your Document
object is not accessible from index.js
as you mention. You need to pass this along to your routes logic, or pass along mongoose itself.
require
calls are cached for the most part, so requiring mongoose in your index.js
file and getting an instance of Document
there is one option.
Since you don't really use Document
in your app.js
, you could always move the db configuration to another module and export the important references back to the scripts that need them.
Upvotes: 1