Reputation: 1166
I set up a web server using node JS and the Express module. My code is as follows :
file tree:
/src
|
+-- server.js
+-- /app
|
+-- routes.js
server.js
// set up ======================================================================
var express = require('express');
var app = express();
var mongoose = require('mongoose');
...
// configuration ===============================================================
mongoose.connect(configDB.url);
...
// routes ======================================================================
require('./app/routes.js')(app, passport);
// launch ======================================================================
app.listen(port);
routes.js
module.exports = function(app, passport) {
app.get('/some-route', function(req, res) {
// this line bugs out
var User = mongoose.model('User', userSchema);
});
};
My question:
Calling mongoose.model() in routes.js throws the following error
ReferenceError:mongoose is not defined
Why is mongoose not known in this context when I've included it in server.js, the file in which routes.js is being included? Should I require() mongoose again in routes.js? What am I missing here?
Upvotes: 0
Views: 712
Reputation: 3053
The modules that are included is on a file are not visible on another file. Here you can find a list of the global objects that are available on every module that you create:
https://nodejs.org/api/globals.html
All the other objects/variables that you define within a file they are defined within the context of this file. Otherwise, this could create huge problems with variables that overwrite other variables in other files and creating a mess within a project. You can think of a file like a function that includes all your code and everything that is defined in there, is not available to the global namespace.
In your case, you have to require('mongoose')
in the files that you need it, and it is built like that so that can maintain the existing connection to the database.
Upvotes: 1
Reputation: 707158
Variables defined within a module are local only to that module. They are not in the scope of other modules that you require()
in with that module. That's why mongoose
is not know to your routes module. The require()
operation does not insert the code right into the calling module. Instead, it loads that code from disk and then inserts it into its own function and calls that function. This gives each loaded module its own independent scope. It is not inserted into the current scope.
In cases like this, you have several choices:
Require()
in the mongoose module again in routes. This is generally preferred when possible because this makes the routes module more self sufficient and easier to reuse as it requires in the things it needs.
Pass in the object you want to share with the routes constructor just like you are passing in app
and passport
. This method is preferred when the item needed by the other module is not just the result of a simple module load. For example, app
is the result of calling a constructor function so the only way for another module to use the same app
instance is for you to pass it.
You can have routes call out to some other module to request information. For example, since you've already passed the app
object to routes, you could put the mongoose
object as either a property on the app
object so it could be referenced that way or you could add a method to the app
object to retrieve it via the method call.
In this case, since mongoose
is just a cached module, it probably makes the most sense to just require()
it in again, but any one of the three methods above would work.
Upvotes: 1