Using variables in modules of Node Express application - javascript

The express generator creates an app like this:
in the main app.js:
var app = express();
//...
var routes = require('./routes/index');
app.use('/', routes);
//...
in routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
What is the best way to use variables that I define in app.js in the index.js?
For example, before defining the routes, I set up the mongoose model:
var myModel;
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.once('open', function (callback) {
//load schemas
var dbSchema = require('./schema');
myModel = mongoose.model('mymodel', dbSchema.myModel);
});
How can I use 'myModel' in the routes module?

You should define your models outside app.js, in their own separate files for each separate model, and export that model which you can then require in various places you need it. Your model definition doesn't actually need to be inside db.once('open'
For example: if you have a model User you should define it in its own file like this:
db/user.js
var mongoose = require('mongoose');
var schema = mongoose.Schema({
…
});
var model = mongoose.model('user', schema);
module.exports = model;
This way if you want to use the User model inside your routes/index.js:
…
var User = require('../db/user');
router.get('/user/:id', function(req, res, next) {
User.findById(req.params.id, function(err, user){
res.render('user', { title: 'Express', user: user});
});
});

Pass it as a parameter when you require your router in your app.js file. You're going to have to slightly modify your index.js file
var express = require('express');
var myRouter = function(myModel) {
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
// You can use your myModel model here
return router;
}
module.exports = myRouter
Now inside your app.js
var app = express();
//...
// Pass myModel as a parameter
var routes = require('./routes/index')(myModel);
app.use('/', routes);
//...

Related

How to pass DB object in multi router setting in ExpressJS?

I would like to make multiple router settings like the example in ExpressJS Doc.
I have index.js , api1 , api2 like below.
How can I pass the db object from index.js to api1 and api2?
I try with
app.use('/api/v1', require('./controllers/api_v1')(db));
but it shows errors:Router.use() requires a middleware function but got a Object
index.js:
var express = require('../..');
const knex = require('knex');
const config = require('./config');
var app = module.exports = express();
const db = knex(config.db);
app.use('/api/v1', require('./controllers/api_v1'));
app.use('/api/v2', require('./controllers/api_v2'));
app.get('/', function(req, res) {
res.send('Hello from root route.')
});
/* istanbul ignore next */
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}
api_v1.js
var express = require('../../..');
var apiv1 = express.Router();
apiv1.get('/', function(req, res) {
res.send('Hello from APIv1 root route.');
});
apiv1.get('/users', function(req, res) {
res.send('List of APIv1 users.');
});
module.exports = apiv1;
api_v2.js
var express = require('../../..');
var apiv2 = express.Router();
apiv2.get('/', function(req, res) {
res.send('Hello from APIv2 root route.');
});
apiv2.get('/users', function(req, res) {
res.send('List of APIv2 users.');
});
module.exports = apiv2;
You could export the db object from a database.js file and require it in the index.js file as well as every other file where you need database access. Or, an easier but uglier method, would be to make the variable global via global.db = db. You could then use db everywhere in your Node.JS application.

load async configs before export

I need to load some async config before run my app, something like this:
var express = require('express');
var router = express.Router();
var myModule = require("myModule");
myModule.create().generateModel().then(tagger => {
router.post('/tag', function(req, res, next) {
res.json(tagger.tag(req.body.text));
});
module.exports = router;
});
but this does not work because require is sync. How can I make this work? How can I reutilize "tagger" in other modules?
You don't need to set module.exports asynchronously because you're exporting the router which is already defined synchronously:
var express = require('express');
var router = express.Router();
var myModule = require("myModule");
myModule.create().generateModel().then(tagger => {
router.post('/tag', function(req, res, next) {
res.json(tagger.tag(req.body.text));
});
});
module.exports = router;

How to use nested middleware in express.js

I want to make a change from the actual structure of my code. This is the actual code i have:
//index.js
var routes = require('./routes');
var subdomain = require('express-subdomain');
//require express app with settings
var app = require('./app');
//export the application
module.exports = app;
// routes request like endusers-api.mydomain.ext/
app.use(subdomain('endusers-api', routes.apis.endusers));
// routes request like mydomain.ext/
app.use(routes.webapps.endusers);
//routes/index.js
var apis = {endusers: require("./apis/endusers")}
var webapps = {endusers: require("./webapps/endusers")}
var routes = {apis: apis, webapps: webapps}
module.exports = routes;
//routes/apis/endusers
var express = require('express');
var route = express.Router();
var logger = require('../../lib/logger');
route.get('/', logger("endusers-api-access"), function(req, res, next) {
res.json({
"name" : "Endusers API"
});
});
module.exports = route;
//routes/webapps/endusers.js
var express = require('express');
var route = express.Router();
var logger = require('../../lib/logger');
route.get('/', logger("endusers-webapp-access"), function(req, res, next) {
res.render('endusers/index', {title: 'Homepage'});
});
module.exports = route;
Now I want to change the above code to this (feel free to tell me if this is a good approach of doing things in Node.js or not):
//index.js
var middlewares = require('./middlewares');
var app = require('./app');
module.exports = app;
//i want to change to this
app.use(middlewares.endusersApi);
app.use(middlewares.endusersWebapp);
//Stuff for creating server and listening...
//middlewares/index.js
var middlewares = {
endusersApi : require("./apis/endusers"),
endusersWebapp : require("./webapps/endusers")
}
module.exports = middlewares;
//middlewares/apis/endusers.js
//TODO
//middlewares/webapps/endusers
//TODO
How should I write the TODO portions above. It look like we will need nested middlewares (a middleware calling another middleware). Please, your suggestions.
I found the answer using by express.Router().all() method.
//middlewares/apis/endusers.js
var routes = require('../../routes');
var express = require('express');
var middleware = express.Router();
middleware.all('/',subdomain('endusers-api', routes.apis.endusers));
//the two next lines are alternatives to the line above
//middleware = subdomain('endusers-api', routes.apis.endusers); //can assign only one route
//middleware.use(subdomain('endusers-api', routes.apis.endusers)); // can use many routes
module.exports = middleware;
//middlewares/webapps/endusers.js
var routes = require('../../routes');
var express = require('express');
var middleware = express.Router();
middleware.all('/', routes.webapps.endusers);
//the two next lines are alternatives to the line above
//middleware = routes.webapps.endusers; //can assign only one route
//middleware.use(routes.webapps.endusers); // can use many routes
module.exports = middleware;

Trying to use exports.create from another module in Node.js

I want to use code from one module in another module.
Module1Directory has the following files:
Module1.js
exports.create = function(req, res) {
function something(){}
}
Index.js:
'use strict';
var express = require('express');
var controller = require('./Module1.js');
var router = express.Router();
router.post('/', controller.create);
module.exports = router;
Module2Directory has the following files:
Module2.js
var confusing = require('../Module1Directory/Module1.js');
exports.create = function(req, res){
confusing.create.something();
}
Index.js:
'use strict';
var express = require('express');
var controller = require('./Module2.js');
var router = express.Router();
router.post('/', controller.create);
module.exports = router;
the function something run in Module2 returns 'undefined is not a function' in the terminal. What's wrong?
Your create is a function, but you're treating it as a non-function object. You'd have to call it, and it would have to return an object with a something property:
Module1.js:
exports.create = function(req, res) {
function something(){}
return {something: something}; // <===
};
Module2.js
var confusing = require('../Module1Directory/Module1.js');
exports.create = function(req, res){
confusing.create(req, res).something();
// ^^^^^^^^^^
};

Cannot figure out how to render a new page in express

I have this ships.js in my routes folder:
var express = require('express');
var router = express.Router();
/* GET Ships page. */
router.get('/ships', function(req, res, next) {
res.render('ships', { title: 'Express' });
});
module.exports = router;
And I have these to statements in my app.js:
var routes = require('./routes/index');
var users = require('./routes/users');
var ships = require('./routes/users');
and
app.use('/', routes);
app.use('/ships', ships);
app.use('/users', users);
However if I navigate to localhost:3000/ships I receive the following message:
respond with a resource
Sorry have read the docs, just not to snazzy with express.
You have two errors in you app module:
1.Invalid require call for ships route:
var ships = require('./routes/users'); <--
// should be:
var ships = require('./routes/ships');
2.Invalid router using in app.use:
app.use('/ships', ships);
// should be:
app.use(ships); // and the same for others

Categories