Node Js Module Layering - javascript

If you had a server js like so:
var app = require('express'),
http = require('http'),
news = require('./server/api/news'),
db = require('mongoose');
/* app config..... */
app.get('/api/news', news.list);
var server = http.createServer(app);
server.listen(app.get('port'), function () {
console.log("Server running");
});
And I wanted to create an API to handle adding news items to the database:
var db = require('mongoose');
/*** Public Interfaces ***/
function list(req, res) {
var offset = ~~req.query.offset || 0,
limit = ~~req.query.limit || 25;
db.News.find(function (err, newsItems) {
res.json(newsItems.slice(offset*limit, offset*limit + limit));
});
}
exports.list = list;
This API would exist in its own file, how do I use the instance of the db created in the server.js inside the new module.
Or do you create and open a new connection each time you query the database?
Thanks

I would probably do it more like this
the server :
var express = require('express'),
app = express(),
http = require('http'),
db = require('mongoose'),
news = require('./server/api/news')(db); // you can pass anything as args
app.get('/api/news', news.list);
/* add routes here, or use a file for the routes */
// app.get('/api/morenews', news.more_news); .... etc
http.createServer(app).listen(8000);
and in the ../news/index.js file or whatever you're using, I'd use a literal, but you can always use exports to pass back each method as well
module.exports = function(db) {
/* now db is always accessible within this scope */
return {
list : function (req, res) {
var offset = ~~req.query.offset || 0,
limit = ~~req.query.limit || 25;
db.News.find(function (err, newsItems) {
res.json(newsItems.slice(offset*limit, offset*limit + limit));
});
}, // now you can easily add more properties
more_news : function(req, res) {
res.end('Hello kitty');
}
}
}

Related

Call a function from module.exports and give value to its parameter

I am building NodeJS code that listens to requests from specific ports and returns a response to it, here is the main code:
module.exports = function (port) {
var fs = require("fs");
var path = require("path");
var express = require('express');
var vhost = require('vhost');
var https = require('https');
var http = require('http');
var bodyParser = require("body-parser");
var normalizedPath = require("path").join(__dirname, "../BlazeData/ssl/");
var options = {
key: fs.readFileSync(normalizedPath + 'spring14.key'),
cert: fs.readFileSync(normalizedPath + 'spring14.cert'),
};
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var normalizedPath = path.join(__dirname, "../WebServices");
fs.readdirSync(normalizedPath).forEach(function(file) {
if (file.indexOf('.js') != -1) {
var url = file.substring(0, file.length - 3);
app.use(vhost(url, require(normalizedPath+"/"+file).app));
console.log( 'Registered Service -> %s:%d', url, port );
}
});
if (port == 80) {
var server = http.createServer(app).listen(port, function(){
console.log("Create HTTP WebServices");
console.log( 'Express server listening on port %d in %s mode', port, app.settings.env );
});
}
if (port == 443) {
var server = https.createServer(options, app).listen(port, function(){
console.log("Create HTTPS WebServices");
console.log( 'Express server listening on port %d in %s mode', port, app.settings.env );
});
}
}
I have another JS file that is used to run the script above, I use
var https1 = require('./clientAuthServer') to initiate the code from above where clientAuthServer.js is the filename of the main code, however it just skips everything from that file.
How would I call module.exports = function (port) from a separate file and give a value to the parameter "port" which the function is using?
When you require your module it returns a function (the function exported by the module). The function is being assigned to the variable https1, so you simply need to call that function because right now it's just being stored.
The simplest way would be for your require statement to look something like this:
const https1 = require("./clientAuthServer")(parameter);
Where parameter is just whatever value you want to pass to the function.

Room not found/ accessible in io object

Currently trying to learn how socket.io works and to create a room based game, but having trouble to get clients to the same room after trying to move my code in a seperated file.
If I use the same code from game.js in my app.js file within io.on("connection")... i´m able to access the room and put players in the same room.
app.js
const express = require("express");
const cors = require("cors");
var http = require("http");
const game = require("./core/game/game");
const app = express();
const port = process.env.PORT || 4001;
const index = require("./routes/index");
const server = http.createServer(app);
const io = require("socket.io")(server, {
cors: {
origin: "*",
},
});
/
app.use(cors({ origin: "*" }));
app.use("/", index);
// Reduce the logging output of Socket.IO
/* io.set('log level',1); */
io.on("connection", (socket) => {
console.log("New client connected");
game.initGame(io, socket);
});
server.listen(port, () => {
console.log(`listening on *:${port}`);
});
game.js
var io;
var gameSocket;
/**
* This function is called by index.js to initialize a new game instance.
*
* #param sio The Socket.IO library
* #param socket The socket object for the connected client.
*/
exports.initGame = function (sio, socket) {
io = sio;
gameSocket = socket;
gameSocket.emit("connected", { message: "You are connected!" });
// Host Events
gameSocket.on("hostCreateNewGame", createRoom);
/* gameSocket.on("hostRoomFull", hostPrepareGame);
gameSocket.on("hostCountdownFinished", hostStartGame);
gameSocket.on("hostNextRound", hostNextRound); */
// Player Events
gameSocket.on("playerJoinGame", addPlayer);
/* gameSocket.on("playerAnswer", playerAnswer);
gameSocket.on("playerRestart", playerRestart); */
};
async function createRoom(data) {
console.log("Create Session");
console.log(data);
console.log(data.username);
var gameId = (Math.random() * 100000) | 0;
console.log(data.username);
console.log(gameId);
//gameSocket.username = username;
gameSocket.join(gameId);
}
async function addPlayer(data) {
console.log("JOIN Session");
console.log(data.gameId);
//console.log(socket.username);
const clients = await io.in(data.gameId).allSockets();
console.log(clients);
if (!clients) {
console.error("[INTERNAL ERROR] Room creation failed!");
}
if (clients.size === 0) {
console.log("room does not exist");
return;
}
console.log(await io.in(data.gameId).allSockets());
gameSocket.username = data.username;
gameSocket.join(gameId);
console.log(await io.in(data.gameId).allSockets());
io.to(data.gameId).emit("joinSuccess", { message: "JUHU" });
If I try to use this code, the clients are always undefined which means I cannot the room from my current io object
const clients = await gameSocket.in(data.gameId).allSockets(); //undefined
Can someone show me what I would need to change in order to access the right io object and find the rooms. Maybe I´m trying to follow a bad approach here when trying to seperate the code from my app.js file.
Any help would be great.
Got this working finally.
The issue was that this returned a real number
var gameId = (Math.random() * 100000) | 0;
Whereas the value send to addPlayers function was a String...

Cannot read property of undefined Node.js

I'm very new to node.js and I'm having struggle with querying to MySQL DB. This is a very simple web page, all I have to do is read the value from the input and search it on my DB.
The problem is that var num is still undefined when the web page executes the query. How do I guarantee that I get that value before executing the query?
var http = require("http");
var url = require('url');
var fs = require('fs');
var io = require('socket.io');
var express = require('express');
var mysql = require('mysql');
var port = process.env.PORT || 8001;
var router = express.Router();
var app = express();
var server = http.createServer(app);
var n_eleitor;
var nome;
var local;
var num_bi;
var num;
// ---- ROUTES ------
app.get('/', function(req, res) { //homepage
res.sendFile(__dirname+'/index.html');
handle_database(req, res);
});
app.get('/result', function(req, res, next) { //results
res.render('result.ejs', { n_eleitor: n_eleitor, local: local, nome: nome });
});
app.use('/', router);
// ---- CONECTION -----
server.listen(port);
var listener = io.listen(server);
listener.sockets.on('connection', function(socket){
socket.on('client_data', function(data){ //receive data from client
//console.log(data.letter);
num_bi = data.letter;
console.log(num_bi);
var num = "'"+num_bi+"'";
console.log(num);
});
});
// ---- MYSQL ------
var pool = mysql.createPool ({ //pool maitains a cache of database connections -> handles multiple connections
connectionLimit : 100,
host : 'localhost',
user : 'root',
password : 'soraia',
database : 'pti2',
});
function handle_database(req, res) {
pool.getConnection(function(err, connection){
if(err){
connection.release(); //connection returns to the pool, ready to be used again by someone else.
return;
}
//console.log('ID:' + connection.threadId);
connection.query("select eleitor.*, freguesia.designacao from freguesia, eleitor where num_bi= ? and freguesia.cod_freg=eleitor.cod_freg",[num], function(err, rows, fields){
n_eleitor = rows[0].cod_eleitor;
nome = rows[0].nome;
local = rows[0].designacao;
connection.release();
console.log(num);
console.log(rows);
});
});
}
When I run the program I get "TypeError: Cannot read property 'cod_eleitor' of undefined" and I think that's because what I said before...
Can someone help me, please?

How to use a node api

So i have found an api for node https://github.com/schme16/node-mangafox
But i have no idea on how to use it
Lets say that i want to use this
mangaFox.getManga = function(callback){
$.get('http://mangafox.me/manga/',function(data){
var list = {};
data.find('.manga_list li a').each(function(index, d){
var b = $(d);
list[mangaFox.fixTitle(b.text())] = {id:b.attr('rel'), title:b.text()};
});
(callback||function(){})(list);
}, true);
}
What should i do to show the list in the '/' route
This i what i have so far
var express = require('express'),
path = require('path'),
mangaFox = require('node-mangafox');
var app = express();
app.get('/', function(req, res) {
});
app.listen(1337);
console.log('oke');
If some cloud help me understand how this works
app.get('/', function(req, res) {
function renderList(data) {
return Object.keys(data);
res.send(JSON.stringify(list));
}
var list = mangaFox.getManga(renderList);
});
This is the simplest thing I can come up with. You just get the object returned by the module, list its keys, and send back that stringified as your response. Try it out. You'll probably want to replace the renderList with some HTML templating.

how to return a value from express middleware as a separate module

I have put the server setting script into a separate js file called server.js. My problem is that I don't know how to get the value of cookie_key from the express middleware function and pass it back to the index.js file.
server.js:
var express = require('express'),
app = express(),
http = require('http').createServer(app),
cookie = cookieParser = require('cookie-parser'),
url = require('url');
module.exports = {
use_app : function(){
app.use(function (req, res, next) {
var cacheTime = 86400000*7; // 7 days
if (!res.getHeader('Cache-Control'))
res.setHeader('Cache-Control', 'public, max-age=' + (cacheTime / 1000));
next();
});
},
get_app : function(callback){
app.use(cookieParser());
app.get('/id/:tagId', function(req, res){ // parse the url parameter to get the file name
function getkey(err,data){ // get users' session cookie
var cookie_key;
if(err)
{
callback(err);
}
cookie_key = req.cookies["session"];
callback(cookie_key);
}
var filename = req.param("tagId");
res.sendFile(filename+'.html');
});
}
}
index.js:
var server = require('./server'),
server.use_app();
server.get_app(); // how to get the cookie_key when calling this function?
console.log(show_cookie_key_from the module);
if(cookie_key !== undefined)
{
// do something
}
I tried to write a callback function to fetch the cookie key but I don't think it's working.
Update from A.B's answer:
var server = require('./server');
server.use_app();
server.get_app(function(cookie){
if(cookie !== undefined)
{
// do something
}
});
But I still think there is something strange about this setup, what exactly are you trying to accomplish with splitting the app up like this?
Since you are using callback function and that is being poplulated with cookie value , you can get this like following:
var server = require('./server');
server.use_app();
server.get_app(function(cookie){
cookie_key= cookie
if(cookie_key !== undefined)
{
// do something
}
});

Categories