How do I expose MongooseSchema objects set in app.js to the routes?
I get this error when trying to use a variable set in app.js from routes/index.js. I've been using node for just a few months, so I'm not sure what I'm missing here.
Please note I am using Express v3.3.4
500 ReferenceError: ProfileSchema is not defined
In my app.js file I have:
var express = require('express')
, util = require('util')
, Promise = require('bluebird')
, crypto = require('crypto')
, routes = require('./routes')
, http = require('http')
, path = require('path');
var ProfileSchema = require('./models/schemas').ProfileSchema;
/*** ..... ***/
app.get('/user/home', routes.user_home);
And in my /routes/index.js I have:
exports.user_home = function(req, res){
//foo
}
I would like to do this inside of that user_home route:
ProfileSchema.find({ users: 'joeblow' }, function (err, docs) {});
But the ReferenceError is thrown, since ProfileSchema is not accesible to the route.
NOTE: I can use ProfileSchema.find() from app.js just fine.
That's because your ProfileSchema
is only defined in app.js, but app.js and /routes/index.js do not share the same scope !
This might be confusing at first, because it's different from client-side JavaScript, but you should take a few minutes to carefully read Node.js docs regarding globals. Quoting from the docs,
In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node this is different. The top-level scope is not the global scope; var something inside a Node module will be local to that module.
To fix your issue, you have two solutions
You can either require your ProfileSchema
directly from
/routes/index.js
var ProfileSchema = require('./models/schemas').ProfileSchema;
exports.user_home = function(req, res){
//ProfileSchema is defined ! Hurray !
}
Or, if you still want to require ProfileSchema
in app.js, you
need to do something that is called dependency injection, which a
complicated word for saying you need to pass your ProfileSchema
variable to /routes/index.js. One way to do that is to export a
function in /routes/index.js that will take ProfileSchema
as a
parameter. So you would need to change your code to :
exports.user_home = function(ProfileSchema){
return function(req, res){
//ProfileSchema is defined ! Hurray !
}
}
And you would pass the parameter in app.js like so :
var ProfileSchema = require('./models/schemas').ProfileSchema;
app.get('/user/home', routes.user_home(ProfileSchema));