What is good pattern to share an object between modules in Nodejs? - node.js

My situation is that I'm working with Websocket, and there is only one websocket server and lot of methods need to get data from server and modify things on server, i.e. delete inactive sockets, etc.
Right now I'm simply passing server instance through function calls and wrapper functions which is getting tedious and is error prone to everything (cyclic dependencies, typos, etc)
Importing server instance causes circular dependencies.
Passing them through parameters causes too much interdependence.
Ex:
onConnection -> attaches events
onMessage = msgHanlder(server);
...
then in msgHandler there are multiple events to take care of
onNewMsg = newMsg(server)
onDelete = delete(server)
onRequest = request(server)
It's very functional style programming but it's too much pain.

Create a caching module ( get,set method ) and require this module to manage your state between different modules.
cache.js
let _cache = {};
module.exports = {
"get":function(key){
return _cache[key];
},
"set":function(key,value){
_cache[key] = value;
}
}
a.js
const cache = require('./cache');
const b = require('./b');
cache.set('a','value set in a');
b.invoke();
b.js
const cache = require('./cache');
module.exports = {
"invoke":function(){
console.log("Module A: ",cache.get('a'));
}
}

Related

How to avoid using global variables in Nodejs?

I have /bin/www that I execute and websocketServer.js that needs the httpServer object from /bin/www to initialize the websocket server. How can I pass httpServer to websocketServer.js without using a global variable?
websocketServer.js:
let WebSocket = require('ws')
let wss = new WebSocket.Server({ server: global.httpServer })
wss.on('connection', (connection, req) =>
...
/bin/www:
let app = require('../app')
let http = require('http')
...
global.httpServer = http.createServer(app)
httpServer.listen(port)
...
I have foo.js and bar.js that both handle user information that is only persistent at runtime (no need to store in database). How can these 2 files work with the same users? I can only think of using a shared variable aka global. Is there any way to avoid using a global variable in this situation? Should I even bother avoiding using global variables if it makes total sense to use them in my mind?
Besides, I came to this situation of needing runtime global variables because so far I've been using a database which is essentially a provider of global variables. Except now my project requires variables that need to be global but don't have to be stored in a database.
foo.js:
...
function getsCalledWhenUserLogsIn(username)
{
global.users[username] = { timer: new Timer(), websocketConnection: null, ... }
// initializing the user below
...
}
...
bar.js:
...
websocketServer.on('connection', (connection, req) =>
{
...
connection.on('message', (message) =>
{
let user = global.users[JSON.parse(message).username]
if (user)
{
user.websocketConnection = connection
...
}
...
}
...
}
...
This is not my code per se but at least it gives you some idea
I want to be able to structure my files in a way that I won't have to use global variables.
Example with global variables:
global.bar = 'hello world';
function foo1() {
console.log(bar);
}
function foo2() {
console.log(bar);
}
foo1();
foo2();
Example without global variables:
var bar = 'hello world';
function foo1(bar) {
console.log(bar);
}
function foo2(bar) {
console.log(bar);
}
foo1(bar);
foo2(bar);
This is overly simplistic, but the main point is: if you want 2 distinct things to have access to the same object without being aware of each other, you need a 'third thing' to pass this object to the first two things.
Also see: dependency injection.
As for the question if you should always do this... I would argue that avoiding globals is something you should always strive for, unless you have a good reason not to. Best practices are a good default, but break them if common sense dictates that you shouldn't apply it for specific cases.
However, I don't think that you have a valid enough case for it here. You just have to learn functions and arguments a bit better.
To avoid global variables you could use XMLHttpRequest and just GET/POST to yourself. Not the most efficient thing but it would still work.
var xhr2 = new XMLHttpRequest();
xhr2.open('GET', "http://yourserver", true);
xhr2.onreadystatechange = function() {
if (this.status == 200 && this.readyState == 4) {
if(this.responseText == '') { return;}
//your code here
}//
};//end onreadystate
xhr2.send();
You could also have global arrays that have objects and just go through them. Then you have one array. It just depends how you want to go about it.

Pass DB context between Node.js module functions

I'm running Express on Node.js and am wondering how I can effectively pass a single database connection context object between distinct Node modules (think of them sort of like application models).
I'd like to do this to be able to start a database transaction in one model and preserve it across calls to other affected models, for the duration of a single HTTP request.
I've seen people attempt to solve this using per-request database connections exposed as middleware before my route is run (taking from a connection pool, then running another piece of middleware after the routes to return the connection to the pool). That unfortunately means explicitly passing around a context object to all the affected functions, which is inelegant and clunky.
I've also seen people talking about the continuation-local-storage and AsyncWrap modules, but I'm unclear how they can solve my particular problem. I tried working with continuation-local-storage briefly but because I primarily use promises and generators in my code, it wasn't able to pass state back from the run method (it simply returns the context object passed into its callback).
Here's an example of what I'm trying to do:
// player-routes.js
router.post('/items/upgrade', wrap(function *(req, res) {
const result = yield playerItem.upgrade(req.body.itemId);
res.json();
});
// player-item.js
const playerItem = {
upgrade: Promise.coroutine(function *(user, itemId) {
return db.withTransaction(function *(conn) {
yield db.queryAsync('UPDATE player_items SET level = level + 1 WHERE id = ?', [itemId]);
yield player.update(user);
return true;
});
})
};
module.exports = playerItem;
// player.js
const player = {
update(user) {
return db.queryAsync('UPDATE players SET last_updated_at = NOW() WHERE id = ?', [user.id]);
})
};
module.exports = player;
// db.js
db.withTransaction = function(genFn) {
return Promise.using(getTransactionConnection(), conn => {
return conn.beginTransactionAsync().then(() => {
const cr = Promise.coroutine(genFn);
return Promise
.try(() => cr(conn))
.then(res => {
return conn.commitAsync().thenReturn(res);
}, err => {
return conn.rollbackAsync()
.then(() => logger.info('Transaction successfully rolled back'))
.catch(e => logger.error(e))
.throw(err);
});
});
});
};
A couple of notes here:
The wrap function is just a little piece of wrapper middleware that allows me to use generators/yield in my routes.
The db module is also just a small wrapper around the popular mysql module, that has been promisified.
What I'd like to do, probably in db.queryAsync, is check if there's a conn object set on the current context (which I'd set around the return Promise... call in db.withTransaction). If so, use that connection to do all subsequent database calls until the context goes out of scope.
Unfortunately, wrapping the return Promise... call in the CLS namespace code didn't allow me to actually return the promise -- it just returned the context object, which is incorrect in my case. It looks like most usages of CLS rely on not actually returning anything from inside the run callback. I also looked at cls-bluebird, but that didn't seem to do what I need it to do, either.
Any ideas? I feel like I'm close, but it's just not all hooking up exactly how I need it to.

Adding or removing EventEmitter.call(this) in my Node example doesn't make any difference, why?

I am new to Node.js and started learning it.
I came across "EventEmitter" in "events" module in node.
After following the example in EventEmitter documentation I wrote the bolow code,
var EventEmitter = require("events");
var util = require("util");
var Ticker = function(){
var self = this;
EventEmitter.call(self);
self.start = function(){
setInterval(function(){
self.emit("tick");
},1000);
}
self.on("tick",function(){
console.log("Keep Ticking");
});
}
util.inherits(Ticker,EventEmitter);
var ticker = new Ticker();
ticker.start();
When I run the code
node example03.js
the output is
rahul#ubuntu:~/rahul/NodePractise/EventEmitter$ node example03.js
Keep Ticking
Keep Ticking
Keep Ticking
Keep Ticking
^C
rahul#ubuntu:~/rahul/NodePractise/EventEmitter$
Now even if I comment the line
//EventEmitter.call(self);
The code works fine.
So whats the purpose of the above line and how is its presence important.
So whats the purpose of the above line and how is its presence
important.
The line of code:
EventEmitter.call(self);
is so the base class (what you inherited from) can properly initialize it's own instance each time you create a new instance of your derived class. This is a very important step that should not be left out.
To explain exactly what it is doing, EventEmitter is the constructor function of the object you derived from. .call(self) is telling Javascript to call that constructor function and to set the this value to the object that was just created (which is pointed to by self in your code). That will end up calling the EventEmitter constructor in the same way as new EventEmitter() would call it which is what you want. The only difference here from new EventEmitter() is that you're pointing this at an instance of your derived object, not at just an EventEmitter object.
In all cases of inheritance, you should call the base class constructor so it can properly initialize itself. But, there may be some types of objects that don't really do much in the constructor so things may happen to work if you leave it out. Or they may just seem to work, but there will be problems down the road.
Adding or removing EventEmitter.call(this) in my Node example doesn't
make any difference, why?
If you look at the EventEmitter code on Github, you can see that the EventEmitter constructor does this:
function EventEmitter() {
EventEmitter.init.call(this);
}
And, the .init() method does this:
EventEmitter.init = function() {
this.domain = null;
if (EventEmitter.usingDomains) {
// if there is an active domain, then attach to it.
domain = domain || require('domain');
if (domain.active && !(this instanceof domain.Domain)) {
this.domain = domain.active;
}
}
if (!this._events || this._events === Object.getPrototypeOf(this)._events) {
this._events = {};
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
So, if you fail to call the parent constructor, there will be several instance variables in the EventEmitter object that are not properly initialized. What this does to the code is anyone's guess (it would take further code study and testing to know for sure), but it is not a good thing. Some features might work without this initialization, but it is very likely that other things will not work properly.

What is good practice when writing a node.js module

I can't really get a grip on what is considered to be good and bad practice when writing a module for in node.js. Some modules seem to use a lot of exports, while other use just one, etc.
Example:
var self;
var mymodule = function() {
self = this;
this.value1 = something;
this.value2 = somethingElse;
};
module.exports.init = function() {
return new mymodule();
};
mymodule.prototype.functionalityType1 = {
someFunction: function(callback) {
var a = self.value1;
anotherfunction(a, callback);
},
};
mymodule.prototype.functionalityType2 = {
someFunction: function(callback) {
var a = self.value2;
anotherfunction(a, callback);
},
};
var anotherfunction = function(v, callback) {
// do stuff with v
callback(result);
};
Each of the prototypes would contain more than one function obviously.
Would something like this be considered good practice?
It really depends on what sort of module you are writing. Exporting multiple functions works well for utility modules which have multiple methods but little to no internal state to manage. Think something like the fs (file system) module. There are a number of file system methods, but they all pretty much stand alone and there is no shared state.
If you're building a stateful module with multiple methods which operate on state then you should probably just export a constructor and allow the client to create an instance of that object that they can manage. An example of this is the http module which allows you to create a server, and that server has methods which affect its internal state.
If you need to have more than one instance of an object from a module then you really don't have much choice but to export a function which returns an instance of the object.
It's not all that different from frameworks like .NET where you have file system (System.IO) classes which have static methods for standalone operations like verifying a directory exists, or reading the contents of a file and then they have instance classes for classes which maintain state.

Namespacing a javascript library, as optional

I'm about to start building a JS library that will have multiple modules. Let's suppose the library is called Library, and two modules will be called One and Two. I'd like for end users to be able to call the library in two different ways:
Library.One.somefunction(params)
or
somefunction(params)
Basically, I want to give the end users the option of including a namespace or not. Is there a good way to do this? Also, is there a good way to do this if I also want to provide a minified version of the library? This library is something that I could end up in Node.js; for now, I'm going to use it myself, but I want to design it in such a way that it's not too hard to turn in to a sharable project in the future.
Any references you can point me to would be great, thanks!
If you're using Node.js you could leverage the CommonJS module system.
math.js (your library)
exports.add = function() {
for (var i = arguments.length; i--;) {
sum += arguments[i];
}
return sum;
};
program.js (someone using it...)
var MyMath = require('math');
console.log(MyMath.add(1, 2)); // 3
// ... in different ways
var add = require('math').add;
console.log(add(1, 2)); // 3
The basic idea behind making a "namespace" optional is to assign the functions to the global scope, which is the window object:
window.somefunction = Library.One.somefunction;
You can write an include function that works similar to other languages:
var include = function (library, p) {
if (!p) {
for (var prop in library) {
if (library.hasOwnProperty(prop)) {
window[prop] = library[prop];
}
}
} else {
window[p] = library[p];
}
};
Then just do, as required:
include(Library.One);
Or use particular functions only:
include(Library.One, 'somefunction');
Warnings:
Executing the functions without the dot notation (One.somefunction) will cause the this keyword to refer to window rather than Library.One. This isn't a problem if you don't use this at all. If you have data to share to between functions then you can do so using closure scope instead of this:
var Library = {};
(function () {
// I'm a closure, I have local scope
var sharedData = "I'm shared but private to this scope";
Library.One = {};
Library.One.funcOne = function () {
alert(sharedData);
};
Library.One.funcTwo = function () {
sharedData += "!";
};
}) ();
Others have well-advised not to make your methods global. This is because once it is global, it is global for all files, and therefore likely to conflict with other code. What you can do is modify the import function above to create a new object, and assign everything to that object before returning it. Then files that need shortcuts to particular libraries can do:
(function () {
var _ = include(Library.One); // This stays within this scope
_.somefunction();
})();
well, i don't know what you mean by "good way".
First of all, the whole purpose of a namespace is to collect variables that are related and not scatter them all around your public namespace.
Personally I wouldn't use such a thing, but you could loop through your namespace's objects and attach them to the window :
for(var i in Namespace)
if(Namespace.hasOwnProperty(i))
window[i] = Namespace[i];
You could do this pretty easily, but are you certain you want to make all the methods global properties?
You could implement it like this (very simplified):
(function( window, undefined ) {
// Your code setting up namespaces
var Library = {One:{},Two:{}};
// function for adding library code to both namespaces.
// Could be modified to accept an Array of functions/names
function addToLibraryOne( id, fn ) {
window[id] = Library.One[id] = fn;
}
// add a function
addToLibraryOne( "somefunction", function( params ) {
// function code
});
window.Library = Library;
})( window );
I'd wonder if you really want to pollute the global namespace like this.
At the very least, I'd make the global properties an option, then only have the function add those if that option is selected.
Well, the second one means that you also want the functions and object and whatever in your modules to be in the global scope. Entirely possible of course, but so against best practices as to be somewhat abhorrent.
For the first part, just declare your Library namespace globally:
var Library = {};
and then start populating it with your modules:
Library.One = {};
Library.Two = {};
and then start adding the functionality to those modules.
(function($) {
var $.froobString = function(s) { .... };
...etc...
})(Library.One);
(Here I've done it as a self-executing anonymous function that passes in Library.One as $.)
To convert all that to globals, have a routine like this:
var convertToGlobals = function(module) {
for (name in module) {
window[name] = module[name];
}
};
convertToGlobals(Library.One)
But then again I'd advise against it.
I might be wrong about this (so this might get downvoted, but I want this evaluated), but I think you are setting up a contradiction with the requirements
1) I want to use namespaces
2) I want to be able to access namespace functionality without the namespace.
basically 2 is "I dont want namespaces".
For implementation, you could just define a bunch of functions globally that route into the namespace, but then why have the namespace to begin with?

Resources