nodejs problems passing a paramenter to module - javascript

I am having a headache trying to pass a variable to module.
In node.js I have the following distribution:
The node.js server (server.js):
// modules =================================================
var express = require('express');
var app = express();
// configuration ===========================================
app.set('port', process.env.PORT || 3000);
var myRoutes = require('./my.router')(app);
// Start the Server ===========================================
app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
exports = module.exports = app; // expose app
The router (my.router.js):
var myCtrl = require('./my.controller');
module.exports = function(app) {
app.get('/api/some', myCtrl.some);
app.get('/api/other', myCtrl.other);
}
The controller(my.controller.js):
exports.some = function(req, res, next) {
res.send('some');
};
exports.other = function(req, res, next) {
res.send('other');
}
This works ok. My problems come when I try to use socket.io and emit an event when /api/some is called.
I need the app object to create the server so I change the router to:
var myCtrl = require('./my.controller');
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
app.get('/api/some', myCtrl.something);
app.get('/api/other', myCtrl.other);
}
And I change the controller to emit the event when /api/some is called:
exports.some = function(req, res, next) {
io.sockets.emit('my_event', {});
res.send('some');
};
exports.other = function(req, res, next) {
res.send('other');
}
Inside the controller I need the io object to make this work.
It may sound simple to someone with a bit more knowledge of node.js but I am not capable of making it work.
I would need something like app.get('/api/some', myCtrl.something(io)) but this is not working...

Can't you just split your code:
var server = require('http').createServer(app);
var io = require('socket.io')(server);
At this stage you have your io, then
var myCtrl = require('./my.controller')(io);
You pass the io as a parameter to your controller which should then be a function like:
/* my.controller.js */
module.exports = function(io) {
some: function(req, res, next) {
io.sockets.emit('my_event', {});
res.send('some');
},
other: function(req, res, next) {
res.send('other');
}
}
Or something along those lines.

// modules =================================================
var express = require('express');
var app = express();
// configuration ===========================================
app.set('port', process.env.PORT || 3000);
var server = require('http').createServer(app);
app.io = require('socket.io')(server); //add io key to app
server.listen(3001);
require('./my.router')(app);
app.Controllers = {};
app.Controllers.myCtrl = require('./my.controller')(app); //pass app to controllers as well (not necessary but you can bootstrap your controllers at the start instead of requiring them in files)
//app.Controllers.anotherCtrl = require('./my.anotherController')(app); //example
// Start the Server ===========================================
app.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
exports = module.exports = app; // expose app
Controller
module.exports = function(app) {
var Controller = {};
var io = app.io;
Controller.some = function(req, res, next) {
io.sockets.emit('my_event', {});
res.send('some');
};
Controller.other = function(req, res, next) {
res.send('other');
}
return Controller;
};
Route
module.exports = function(app) {
var myCtrl = app.Controllers.myCtrl;
app.get('/api/some', myCtrl.some);
app.get('/api/other', myCtrl.other);
}

You can use the request object to pass the data between different routes.
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
//middleware used to assign 'io' to the request object
function passIoObject(req, res, next) {
req.myIo = io;
next()
}
// either use app.use(passIoObject) if io should be available for all following routes
// or pass it only to specific routes
app.get('/api/some', passIoObject, myCtrl.something);
app.get('/api/other', myCtrl.other);
}
and in your main controller you would access it using:
exports.some = function(req, res, next) {
req.myIo.sockets.emit('my_event', {});
res.send('some');
}
Beside that you should avoid a construct like:
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
app.get('/api/some', myCtrl.something);
app.get('/api/other', myCtrl.other);
}
The larger the code becomes the more problems you will have with maintainability, because you will always need look into the require('./my.router') file to see which paths/prefix are handled by the code.
Instead write it that way:
module.exports = function(app) {
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(3001);
var router = express.Router();
router.get('/some', myCtrl.something);
router.get('/other', myCtrl.other);
return router;
}
And in server.js
var myRoutes = require('./my.router')(app);
app.use('/api', myRoutes);

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.

How to get my node.js mocha test running?

I have developed a service in node.js and looking to create my first ever mocha test for this in a seperate file test.js, so I can run the test like this:
mocha test
I could not figure out how to get the reference to my app, routes.js:
var _ = require('underscore');
module.exports = function (app) {
app.post('/*', function (req, res) {
var schema={
type: Object,
"schema":
{
"totalRecords": {type:Number}
}
};
var isvalid = require('isvalid');
var validJson=true;
isvalid(req.body,schema
, function(err, validObj) {
if (!validObj) {
validJson = false;
}
handleRequest(validJson,res,err,req);
});
})
}
This is the server.js:
// set up ======================================================================
var express = require('express');
var app = express(); // create our app w/ express
var port = process.env.PORT || 8080; // set the port
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use (function (error, req, res, next){
res.setHeader('content-type', 'application/json');
res.status(400);
res.json({
"error": "errormsg"
});
});
// routes ======================================================================
require('./routes.js')(app);
// listen (start app with node server.js) ======================================
app.listen(port);
console.log("App listening on port " + port);
And finally test.js:
"use strict";
var request = require('supertest');
var assert = require('assert');
var express = require('express');
var app = express();
describe('testing filter', function() {
it('should return an error', function (done) {
request(app)
.post('/')
.send({"hh":"ss"})
.expect(400,{"error": "errormsg"})
.end(function (err, res) {
if (err) {
done(err);
} else {
done();
}
});
});
});
Create a separate file called app.js. The only purpose of this file would be to run the server. You'll also need to export your app object from server.js. So, your server.js would look like this
// set up ======================================================================
var express = require('express');
var app = express(); // create our app w/ express
var port = process.env.PORT || 8080; // set the port
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use (function (error, req, res, next){
res.setHeader('content-type', 'application/json');
res.status(400);
res.json({
"error": "errormsg"
});
});
// routes ======================================================================
require('./routes.js')(app);
module.exports = app;
Create a new file called app.js and put this inside of it
var app = require('./app');
var port = process.env.port || 8000;
app.listen(port, function() {
console.log("App listening on port " + port);
});
Now, inside of your test file, import your app as follows
var request = require('supertest');
var assert = require('assert');
var app = require('./app.js');
....
Note that I assume all your files are in the same directory. If you've put your test file in a different folder then you'll need to give the right path while requiring your app object.

Node app route is not working

Im fairly new to node JS and I've created the following 3 files and when save the application I got error
http.createServer(app).listen(**app.get('port')**, function(){
the error is undefined is not a function
I use nodemon and I see the error in the terminal
I want to keep the structure of the files(to initiate the server from different file - server.js )since I want to use TDD .
this is the files
server.js
var http = require('http');
app = require('./app');
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
app.js
module.exports = function() {
var express = require('express'),
app = express();
app.set('port', process.env.PORT || 3000);
app.use(require('./controllers/requests'));
return app;
}
requests.js
var routers = require('express')
, router = express.Router()
router.get('/wild', function(req, res) {
debugger;
res.send('Wolf, Fox, Eagle')
})
module.exports = router
UPDATE
This is the update in the code
app.js
module.exports = function() {
var express = require('express'),
app = express();
app.set('port', process.env.PORT || 3000);
app.use(function(){
var routes = require('./controllers/requests') (app);
});
return app;
}
requests.js
**
module.exports = function (app) {
var express = require('express')
, router = express.Router();
app.get('/wild', function(req, res) {
res.send('Wolf, Fox, Eagle');
})
}
server.js
var http = require('http');
app = require('./app');
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});**
You should invoke the function returned by module containing app.
app = require('./app') ();
Moreover, in request.js file you should define routes on your app instance:
module.exports = function (app) {
app.get('/wild', function(req, res) {
res.send('Wolf, Fox, Eagle');
})
}
And in app.js:
app.use(function () {}) is used to define middlewares. Here you could call
var routes = require('./controllers/requests') (app);
EDIT
Please find here below the recap to answer your comments:
server.js
var http = require('http');
var app = require('./app') ();
http.createServer(app).listen(app.get('port'), function(err){
console.log('Express server listening on port ' + app.get('port'));
});
app.js
module.exports = function() {
var express = require('express'),
app = express();
app.set('port', process.env.PORT || 3000);
require('./controllers/requests')(app);
return app;
}
requests.js
module.exports = function (app) {
app.get('/wild', function(req, res) {
res.send('Wolf, Fox, Eagle')
});
}
Hope this helps!

Express 4 : I have a variable set up in app.js and I need to send it to my routes

Here's what I have added to my app.js page. (using express generator)
app.js
var express = require('express');
var socket_io = require( "socket.io" );
var app = express();
// Socket.io
var io = socket_io();
app.io = io;
Now if I were to do the following:
io.on('connection', function (socket) {
console.log("connection made!");
});
This works nicely! But I'm wondering, how do I send socket_io to my route? For example I have a route called 'playground' and I would like to use socket_io specifically inside that route. I don't know how to do so! Any help would be great and I hope I was descriptive enough!
There are many ways to do this.
You can pass io as a function argument to your route module:
app.js
var express = require('express');
var socket_io = require( "socket.io" );
var app = express();
// Socket.io
var io = socket_io();
var route = require('./route')(io);
route.js
module.exports = function(io) {
io.on('connection', function (socket) {
console.log("connection made!");
});
};
Or you can export an init method:
route.js
module.exports.init = function(io) {
io.on('connection', function (socket) {
console.log("connection made!");
});
};
Or you can define a constructor for your route:
app.js
var express = require('express');
var socket_io = require( "socket.io" );
var app = express();
// Socket.io
var io = socket_io();
var Route = require('./route');
var r = new Route(io);
r.doSomething();
route.js
var Route = function(io) {
this.io = io;
io.on('connection', function (socket) {
console.log("connection made!");
});
};
Route.prototype.doSomething = function() {
console.log('hi');
};
// route.js
module.exports = Route;

structure and use in app socket.io

I want to have a structure for my application, but do not know how to call socket.io from sub-router and attach it to the server express
//app.js
var express = require('express')
, http = require('http')
, path = require('path'):
, i18n = require("i18n");
var app = express();
.
.
app.use(app.router);
require('./routes')(app);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express port " + app.get('port'));
});
//routes.js
module.exports = function (app) {
var rou_admin = require('./routers/admin')
, rou_login = require('./routers/login')
, rou_page = require('./routers/page')
, rou_logou = require('./routers/logout');
function restrict(req, res, next) {
if (req.session.user){
next();
} else {
res.redirect('/login');
}
}
//General
app.get('/', rou_page.page);
//Admin
app.get('/admin', rou_admin.admin);
//xxxx
app.get('/xxxx', rou_admin.xxxx);
//ssss
app.get('/ssss', rou_admin.ssss);
.
.
};
//routes/admin.js
exports.admin = function(req, res){
res.render('index',{title: 'Chat Room'})
var io = require('socket.io').listen(app);
io.sockets.on('connection', function(socket) {
...code...
}
};
How could I do this, If you have a lot better idea.
var io = require('socket.io').listen(app);
You already got most of the solution. Just make few changes :
routes.js
module.exports = function (app) {
var rou_admin = require('./routers/admin')(app), //pass app to routes/admin.js itself
routes/admin.js
function admin(app)
{
admin.start= function(req, res){
res.render('index',{title: 'Chat Room'})
var io = require('socket.io').listen(app);
...code...
};
}
module.exports = admin;
here it just defines the function, you can use admin.start() to execute your code.

Categories