Should I require in each module? - node.js

I don't know how to structure my code or rather I don't know what happens when an app is built with the below structure. I need to use redis, so is it ok to call it in each module or is this a bad practice?
I have 10 functions that I want to have in separate modules to keep my code readable. I am using express js.
So I have an index.js which looks like this:
const express = require("express");
const app = express();
const port = 3001;
// the separate modules I want to make
let myFirst = require("./first_function");
let mySecond = require("./second_function");
//etc...
app.use("/my_route1",myFirst);
app.use("/my_route2",mySecond);
app.listen(port, () => console.log(`Listnening on port ${port}`));
The first_function.js file looks like this:
const express = require("express");
const router = express.Router();
const redis = require("redis");
const { promisify } = require("util");
const REDISHOST = process.env.REDISHOST;
const REDISPORT = process.env.REDISPORT;
const redisClient = redis.createClient(REDISPORT, REDISHOST);
const getAsync = promisify(redisClient.get).bind(redisClient);
redisClient.on("error", function(err) {
return;
// but since this is an http function should I be calling res.end()?
});
router.all("/", (req,res) =>{
// code for my function
});
module.exports = router;
I will be using redis in quite a few of the modules, so would it just be better to make the index.js file thousands of lines of code or whatever it may come out to be? I don't quite understand what happens when a module is required, if I use 10 modules which all require redis and then require those modules from index.js will I end up with 10 redis clients?

const redis = require('redis');
class Connection {
constructor() {
this.redisClient = redis.createClient({host : "<hostname>", port : "<port>"});
let methods = {};
methods.redisF = false;
if(this.redisconf.cache) {
this.redisClient.on('ready',function() {
methods.redisF = true;
console.log(" Redis cache is up and running ... ");
});
}
this.redisClient.on('error',function() {
methods.redisF = false;
});
}
static makeRedisConnection() {
try {
return this.redisClient;
} catch(error) {
throw "error"
}
}
}
module.exports = Connection;
Whenever you want to query from redis, take the connection in any of the async function from any other module in the below manner, it will help you write less and more structured code.
const redis_conn = Connection.makeRedisConnection();

Related

Why does exporting the socket.io server as a constant using module.exports? make it undefined?

I am runnnig a socketserver in express but I am unable to export the io constant to a different file without it becoming undefined. I, therefore, cannot use io.on( ), it gives a type error. When i tried to console.log it, its undefined. Please help
server.js:
const app = require("express")();
const httpServer = require("http").createServer(app);
const io = require("socket.io")(httpServer, options);
// const io = new Server(server, options)
io.on("connection", socket => { console.log('hello') });
...
module.exports = {httpServer, app, io};
router.js:
const {io} = require("../server.js");
// console.log(io)

Nodejs TypeError "is not a constructor"

I am working through the course "Build a Blockchain and Cryptocurrency From Scratch from Udemy. I have no prior experience with NodeJS I have been following along with the instructor's code, but recently hit a snag that I cannot resolve. When trying to build the project to run test scripts via npm run dev, I get the following error:
/home/OnlyDean/Workspace/udemy_blockchain_course_1/app/index.js:13
const p2pServer = new P2pServer(bc);
^
TypeError: P2pServer is not a constructor
Answers I've found online seem to indicate that I'm calling an instance of the class P2pServer rather than the constructor of the class itself. This is borne out by the output of console.log(P2pServer);, which returns [Object object]. I have scoured the code for errors, and compared my code to what the instructor has on the screen. I can't seem to find any differences. Below are my index.js and p2p-server.js classes, which I think are the only relevant files.
index.js
const express = require('express');
const bodyParser = require('body-parser');
const Blockchain = require('../blockchain');
const P2pServer = require('./p2p-server');
const HTTP_PORT = process.env.HTTP_PORT || 3001;
const app = express();
const bc = new Blockchain();
//console.log(`Blockchain = ${Blockchain}`)
console.log(`P2pServer = ${P2pServer}`)
console.log(bc)
const p2pServer = new P2pServer(bc);
app.use(bodyParser.json());
app.get('/blocks', (req, res) => {
res.json(bc.chain);
})
app.post('/mine', (req, res) => {
const block = bc.addBlock(req.body.data);
console.log(`New block added: ${block.toString()}`);
res.redirect('/blocks');
});
app.listen(HTTP_PORT, () => console.log(`Listening on port ${HTTP_PORT}`));
p2pServer.listen();
p2p-server.js
const Websocket = require('ws');
const P2P_PORT = process.env.P2P_PORT || 5001;
const peers = process.env.PEERS ? process.env.PEERS.split(',') : [];
class P2pServer {
constructor(blockchain) {
this.blockchain = blockchain;
this.sockets = [];
}
listen() {
const server = new Websocket.Server({ port: P2P_PORT});
server.on('connection', socket => this.connectSocket(socket));
this.connectToPeers();
console.log(`Listening for peer-to-peer connections on: ${P2P_PORT}`);
}
connectToPeers() {
peers.forEach(peer => {
const socket = new Websocket(peer);
socket.on('open', () => this.connectSocket(socket));
});
}
connectSocket(socket) {
this.sockets.push(socket);
console.log(`Socket connected`);
}
}
module.export = P2pServer;
Any help resolving this error would be greatly appreciated -- I'm kind of stuck with the course until I can resolve this. Thanks!
The problem is at the export of the P2pServer class
should be like this (exports and not export):
module.exports = P2pServer;

The object from my Node module does not have the behavior I expect - Node.js

I am a newbie with Node and I am trying to learn how to make my modules work. Here is my express app:
var express = require('express');
var app = express();
var client = require('./config/postgres.js');
app.get('/users', function(req, res) {
var query = client.query('SELECT * FROM users');
query.on('row', function(row, result) {
result.addRow(row);
});
query.on('end', function(result) {
res.json(result);
});
});
And here is my module that I am trying to require
var pg = require('pg').native;
var connectionString = process.env.DATABASE_URL || 'postgres://localhost:5432/isx';
var client = new pg.Client(connectionString);
client.connect();
module.exports.client = client;
but in my main app, my client has no method 'query'. If I just inline the code that is in the module and I am requireing in, then everything works fine. What is the difference between the 2 ways to access the code?
var client = require('./config/postgres.js');
...sets client equal to the export object in your import. Since the export object has a single client property with the query function,
client.client.query()
is what you're looking for.
If you want to export just the client, use;
module.exports = client;
Your are exporting this:
{
"client": [Function]
}
Just access the key that stores the function when you require the module or export only the function and nothing more:
module.exports = client;

Node.js + Express passing an object

I'm building a small node.js/express project and have a function in configure.js that sets configuration options in my express app. For example:
server.js
var express = require('express');
var server = ('./configure');
var app = express();
server.configure(app);
configure.js
exports.configure = function(app) {
app.set('title', 'Server');
};
This doesn't work but I hope it explains what I'm trying to do. I want to make changes to the app instance in server.js. How do I do this?
EDIT:
Okay I think i can get this all working if i understand why this isn't working. Is it to do with timing of the callback? The second console.log() isn't called.
configure.js
var fs = require('fs');
var StringDecoder = require('string_decoder').StringDecoder;
var decoder = new StringDecoder('utf8');
function configure(app) {
var config = module.exports = {};
fs.readFile('config.txt', function (err, data) {
if (err) throw err;
config.title = decoder.write(data)
console.log(config.title)
});
if(config.title) console.log(config.title);
//app.set('title', config.title)
}
module.exports = function (app) {
configure(app);
};
server.js
var express = require('express');
var cfg = require('./configure');
var fs = require('fs');
var app = express()
cfg(app)
(config.txt is echo 'server' > config.txt)
What you have should actually work.
As for your question about using multiple functions, you can export and call each separately. This can be useful when timing is important (such as if other setup steps need to occur that aren't specified in configure.js):
// configure.js
exports.configure = function (app) {
// ...
};
exports.attachMiddlware = function (app) {
// ...
};
// server.js
var express = require('express');
var server = require('./configure');
var app = express();
server.configure(app);
server.attachMiddlware(app);
You can also define a single entry function as the exported object which calls the functions needed within configure.js. This can possibly keep server.js cleaner by isolating the maintenance within configure.js:
function configure(app) {
// ...
}
function attachMiddleware(app) {
// ...
}
module.exports = function (app) {
configure(app);
attachMiddleware(app)
};
var express = require('express');
var configure = require('./configure');
var app = express();
configure(app);
I would avoid that and just do a json object:
app.js
var cfg = require('./config');
app.set('title', cfg.title);
config.js
var config = module.exports = {};
config.title = 'Server';

multiple usage of require() in Node.js return undefined results

I've got really strange behavior of require() in node.js.
I have simple common.js:
module.exports = common = {
config: require('./config/config'),
errorCodes: require('./config/errorCodes'),
server: require('./server/server').server,
dbManager: require('./db/dbManager').dbManager,
idGenerator: require('./utils/idGenerator').idGenerator
};
my server.js:
var http = require('http'),
url = require("url"),
common = require('../common');
var server = (function ()
{
var server = http.createServer(function (request, response)
{
});
// running server
function startServer()
{
server.listen(common.config.port);
console.log('Tracking server running at :' + common.config.port);
}
return {
startServer: startServer
};
})();
module.exports.server = server;
So, Case 1, - I'm reqiuring common only in server.js, it works:
start.js:
//var common = require('./common');
var server = require('./server/server').server;
// initialize whole server
var init = function ()
{
// common.dbManager.init();
server.startServer();
};
init();
And, Case 2, I'm requiring common in both modules - doesn't work:
start.js
var common = require('./common');
var server = require('./server/server').server;
// initialize whole server
var init = function ()
{
common.dbManager.init();
server.startServer();
};
init();
The error is that in the second case certain properies common.config and common.dbManager are undefined. Does anybody have an idea why?
Thanks in advance.
Update
Thanks guys, the following solution works:
Your 'common' model is not needed: just require modules you need
explicitly
You have a cycle: server -> common -> server.
Node.js require() returns undefined (by design) when module that is being loaded is required again, in cycle.
Solve your cycle.

Resources