Wrapping NodeJS's net.createServer into a producer of customised sockets - node.js

I'm trying to make a function which behaves like net.createServer, except that it returns objects which are wrappers around sockets, instead of sockets.
(The point of these will be to do automatic data conversion.)
My latest attempt looks like:
var net = require('net');
var util = require('util');
var stream = require('stream');
var EventEmitter = process.EventEmitter;
exports.createServer = createServer;
function createServer(arg0, arg1) {
var server;
var netServer;
var ocb;
if (typeof arg1 === 'function') {
// options, callback
netServer = net.createServer(arg0, callback);
ocb = arg1;
} else if (typeof arg0 === 'function') {
// callback
netServer = net.createServer(callback);
ocb = arg0;
} else {
// options?
netServer = net.createServer(arg0);
ocb = null;
}
server = new Server(netServer);
function callback(socket) {
ocb(new LiftedSocket(socket));
};
return server;
;
}
function Server(netServer) {
this.netServer = netServer;
}
util.inherits(Server, EventEmitter);
Server.prototype.listen = function() {
this.netServer.listen.apply(this.netServer, arguments);
}
function LiftedSocket(socket) {
stream.Duplex(this);
this.socket = socket;
}
util.inherits(LiftedSocket, stream.Duplex);
LiftedSocket.prototype._read = function(size) {
console.log('_read', size);
// transforming code goes here
this.socket.read(size);
}
LiftedSocket.prototype._write = function(chunk, encoding, callback) {
console.log('_write', chunk, encoding, callback);
// transforming code goes here
this.socket.write(chunk, callback);
}
But when tested (by trying to pipe from a returned LiftedSocket) it fails with errors including:
Uncaught TypeError: Cannot read property 'pipesCount' of undefined
at LiftedSocket.Readable.pipe (_stream_readable.js:453:16)
Uncaught TypeError: Cannot read property 'flowing' of undefined
at LiftedSocket.Readable.on (_stream_readable.js:691:44)
I expect I'm doing something wrong when constructing the LiftedSocket, but I can't think what.

I had called the superclass constructor incorrectly. It should have been:
stream.Duplex.call(this, {})

Related

Get data from nested foreach

I'm building an app using firebase and Node.js. I need to get data from nested foreach. How to do it correctly? Need to return the results of all iterations simultaneously.
exports.userParty = function (userInfo, cb) {
var userID = userInfo.userID;
var clubID = userInfo.clubID;
var refUserParty = ref.child(userID).child('my_party_id');
var party = {};
refUserParty.orderByValue().once("value", function (snapshot) {
var party = {};
snapshot.forEach(function (partyID) {
var refParty = dbb.ref('clubs').child(clubID).child('party').child(partyID.val());
refParty.once('value', function (partyBody) {
party[partyID.val()] = partyBody.val();
//console.log(party);
});
});
cb(party); // {}
});
};
You need to call the callback after all the async functions in the forEach block have completed. You can do this using a simple counter to check all async functions are complete:
...
let completedSnapshots = 0;
snapshot.forEach(function (partyID) {
var refParty = dbb.ref('clubs').child(clubID).child('party').child(partyID.val());
refParty.once('value', function (partyBody) {
party[partyID.val()] = partyBody.val();
completedSnapshots++;
if (completedSnapshots === snapshot.val().length) {
cb(party);
}
});
});
...

Variable precedence (global in node js?)

"use strict";
var Tabletop = require("tabletop");
var base64 = require('base-64');
Tabletop.init( { key: 'xxxxxg46hgfjd',
callback: showInfo,
simpleSheet: true } )
function showInfo(data, tabletop) {
console.log(data);
console.log(base64.encode(data));
}
var vGlobals = {
dataString: base64.encode(data)
};
module.exports = vGlobals;
How can I access the data variable from showInfo, to use in vGlobals? It says that it hasn't been defined.
Your approach is wrong, you can't do it this way because TableTop call your callback asynchronously.
My suggestion (a quick one) :
var dataString = null;
module.exports = function(cb) {
if (dataString == null)
Tabletop.init({
key: 'xxxxxg46hgfjd',
callback: function(data, tabletop) {
dataString = base64.encode(data);
cb(dataString);
},
simpleSheet: true
});
else cb(dataString);
};
And to get the data :
var dataManager = require('./myfile');
dataManager(function(dataString) {
//here is your data do what you want with it
})
You should look/learn more about node/javascript and asynchronous/event-driven programing.

has no method of emit in node.js

I made a simple example like below, and I got a error saying 'has no method of 'emit' ', what is the issue ?
var events = require('events');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Door = function (options) {
events.EventEmitter.call(this);
}
util.inherits(Door, EventEmitter);
Door.prototype = {
open:function(){
this.emit('open');
}
}
var frontDoor = new Door('brown');
frontDoor.on('open', function() {
console.log('ring ring ring');
});
frontDoor.open();
You are replacing the prototype of Door with a new object, which overwrites (/removes) the EventEmitter prototype methods as well:
Door.prototype = {
open:function(){
this.emit('open');
}
}
Instead, just add a single entry to the existing prototype:
Door.prototype.open = function() {
this.emit('open');
};

Need help in passing this simple mocha test in javascript

Here, I wrote a simple utilities class in Javascript that parses and stringify Json data.
//public/js/utilities.js
function UtilitiesClass(){
var parserJson = function(obj){
if (typeof(obj) !== "undefined") {
return JSON.parse(obj);
};
}
var stringifyJson = function(obj){
if (typeof(obj) !== "undefined") {
return JSON.stringify(obj);
};
}
}
module.exports = UtilitiesClass
Then in my test.js
require('../public/js/utilities.js');
describe('JS Utilities Classs Tests', function () {
var jsonObjToStr, strtojsonObj;
beforeEach(function () {
this.jsonObjToStr = [1, 2, 3, 4];
this.strtojsonObj = "[1, 2, 3, 4]";
});
it('should parse a string into JSON ', function () {
expect(parserJson(this.strtojsonObj)).to.not.be.undefined;
});
it('should stringify JSON into a string', function () {
expect(stringifyJson(this.jsonObjToStr)).to.not.be.undefined;
});
});
Then when I tried running mocha, I got the following error output.
andy#LINUXAWCM:~/Projects/Javascript/e-shop-gadgets$ mocha
JS Utilities Classs Tests
1) should parse a string into JSON
2) should stringify JSON into a string
0 passing (12ms)
2 failing
1) JS Utilities Classs Tests should parse a string into JSON :
ReferenceError: parserJson is not defined
at Context.<anonymous> (test/test.js:12:18)
2) JS Utilities Classs Tests should stringify JSON into a string:
ReferenceError: stringifyJson is not defined
at Context.<anonymous> (test/test.js:16:16)
Why wouldn't this simply work? The require statement on public/js/utilities.js comes out fine. But it's saying the parserJson and stringifyJson are not defined or found when really it's already loaded.
Isn't it?
Simply declaring a variable inside a function is not enough, you need to return these since they aren't available outside the function's scope.
You're also exporting a function and not calling it.
Also requiring a file doesn't magically make your variables available to your scope.
//public/js/utilities.js
function UtilitiesClass(){
var parserJson = function(obj){
if (typeof(obj) !== "undefined") {
return JSON.parse(obj);
};
}
var stringifyJson = function(obj){
if (typeof(obj) !== "undefined") {
return JSON.stringify(obj);
};
}
return {
parserJson: parserJson,
stringifyJson: stringifyJson
};
}
module.exports = UtilitiesClass;
var util = require('../public/js/utilities.js')();
util.parserJson(...) //etc
Though you probably don't need to export a function, just each method.
//public/js/utilities.js
var parserJson = function(obj){
if (typeof(obj) !== "undefined") {
return JSON.parse(obj);
};
}
var stringifyJson = function(obj){
if (typeof(obj) !== "undefined") {
return JSON.stringify(obj);
};
}
module.exports = {
parserJson: parserJson,
stringifyJson: stringifyJson
};
Then you'd use
var utils = require('../public/js/utilities.js');

Access private function in Node Module

I have a function exposed through export in a node module I'm building. I'd like to be able to have that function call an internal (private) function within the same module.
So far I have something like:
someModule.js
var publicFunc = function(a, b) {
var obj = {result: 'of some processing'};
return privateFunc(obj);
}
var privateFunc = function(obj) {
/* proccessing */
return result;
}
exports.publicFunc = publicFunc;
When publicFunc calls privateFunc I get:
Reference error: privateFunc is not defined;
Change your declarations to function name(... instead of var name = function(...
function publicFunc(a, b) {
var obj = {result: 'of some processing'};
return privateFunc(obj);
}
function privateFunc (obj) {
/* proccessing */
return result;
}
exports.publicFunc = publicFunc;

Resources