Access private function in Node Module - node.js

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;

Related

How we call recursive function in node js

My code is below:
module.exports = {
cleanCode: function(){
return 'clean code helper'
},
nestedChildren: function(arr, parentId) {
var out = []
for (var i in arr) {
if (arr[i].parent_id == parentId) {
var children = nestedChildren(arr, arr[i].id)
if (children.length) {
arr[i].subCate = children
}
out.push(arr[i])
}
}
return out
}
}
Getting following error {"message":"nestedChildren is not defined"}
As #jonrsharpe suggested, move the function outside of the export:
let nestedChildren = function(arr, parentId) {
var out = [];
for (var i in arr) {
if (arr[i].parent_id == parentId) {
var children = nestedChildren(arr, arr[i].id);
if (children.length) {
arr[i].subCate = children;
}
out.push(arr[i]);
}
}
return out;
};
module.exports = {
nestedChildren,
cleanCode: function(){
return 'clean code helper';
}
};
Properties of an JavaScript Object cannot reference themselves or any other property of the same object. Thus, a recursive function within an object is not possible.
To work around this problem, you can move the function to the upper scope (outside of the object) where it's accessible from within the object.
So what I did was defining the function outside of the object as standalone function and then I referenced it in your export.
module.exports = {
nestedChildren,
...
};
is just a shorthand for
module.exports = {
nestedChildren: nestedChildren,
...
};

Nodejs module without parameters

I am developing a Nodejs module, which is a function and returns an object with a function in a property. If I call the module without any parameter returns error (Test is not a constructor). If I call the module passing a parameter, even if it is empty, it works properly.
Example #1
(App)
//var test = require('./index.js')().Test; // Works properly
var test = require('./index.js').Test;
var sample = new test('text', function(newText) {
console.log(newText);
});
(Module)
module.exports = function(options) {
var bold = 0;
var anotheModule = new anotherModule(options); //If the parameters are not defined, take the default.
console.log('Check 1');
return {
Test: Test
}
function Test(text) {
.....
}
}
Example #2
(Module)
module.exports = function textChange(options) {
var bold = 0;
var anotheModule = new anotherModule(options); //If the parameters are not defined, take the default.
console.log('Check 1');
}
textChange.prototype.Test = function(text) {
.....
}
Example #3
(Module)
function textChange(options) {
var bold = 0;
var anotheModule = new anotherModule(options); //If the parameters are not defined, take the default.
console.log('Check 1');
}
textChange.prototype.Test = function(text) {
.....
}
module.exports = textChange;
Example #4
(Module)
function textChange(options) {
var bold = 0;
var anotheModule = new anotherModule(options); //If the parameters are not defined, take the default.
console.log('Check 1');
}
Test = function(text) {
.....
}
module.exports = textChange;
export.Test = Test;
I can't get the solution to work without passing parameters. I can't get the solution to work without passing parameters. If the application calls the module with parameters, it works correctly.
The error Test is not a constructor that you're getting it is because you're using the new keyword on undefined. Since Test is undefined.
const test = undefined;
try {
new test();
} catch(e) {
console.log(e.message);
}
In your example #1 you're exporting a function that when executed returns an object containing Test, that's why you need to use () on the exported module.
In your example #2 & #3, you're exporting a function (constructor), so it is the instance of textChange which has the Test method:
const textChange = require('./index.js');
new textChange().Test();
Note: Your example #2 will throw a ReferenceError, textChange is not defined since you're assigning it directly to module.exports, so it should be:
module.exports = function textChange(options) {
var bold = 0;
console.log('Check 1');
}
module.exports.prototype.Test = function(text) {
/* ... */
}
In your last example, the last line: export should be exports but it won't do what you're expecting.
What's being exported it's module.exports, which is a function, textChange to be precise, so Test will never be available outside of that module.
var test = require('./module.js');
console.log(test.Test); // undefined
Check this question: module.exports vs exports in Node.js
I don't know exactly what you're trying to achieve, but if you want
var test = require('./index.js').Test;
You should export an object containing Test property.
Module
module.exports = {
Test(text) {
/* ... */
}
}
or
function Test(text) {
console.log('Text: ', text);
}
module.exports.Test = Test;

Initialize a module when it's required

I have a module with some initialization code inside. The init should be performed when the module is loaded. At the moment I'm doing it like this:
// in the module
exports.init = function(config) { do it }
// in main
var mod = require('myModule');
mod.init(myConfig)
That works, but I'd like to be more concise:
var mod = require('myModule').init('myConfig')
What should init return in order to keep mod reference working?
You can return this, which is a reference to exports in this case.
exports.init = function(init) {
console.log(init);
return this;
};
exports.myMethod = function() {
console.log('Has access to this');
}
var mod = require('./module.js').init('test'); //Prints 'test'
mod.myMethod(); //Will print 'Has access to this.'
Or you could use a constructor:
module.exports = function(config) {
this.config = config;
this.myMethod = function() {
console.log('Has access to this');
};
return this;
};
var myModule = require('./module.js')(config);
myModule.myMethod(); //Prints 'Has access to this'

Serialization of a polymorphic array in node.js

I am looking for a method for serialization of a Javascript object, that contains several other objects of different classes, with function arguments.
Here is a simple test-case:
// Paper class:
function Paper(name) {
this.name = name;
}
Paper.prototype = {
string: function() { return "Paper:"+this.name; }
};
// Book class:
function Book(name) {
this.name = name;
}
Book.prototype = {
string: function() { return "Book:"+this.name; }
};
// Library class:
function Library(name) {
this.items = [];
}
Library.prototype = {
add: function(item) { this.items.push(item); },
string: function () {
var titles = this.items.map(function(item) { return item.string(); });
return titles.join(",");
},
};
///// Define a library:
var lib = new Library();
lib.add(new Paper("MyPaper"));
lib.add(new Book("MyBook"));
assert(lib.string() == "Paper:MyPaper,Book:MyBook");
///// Serialize, de-serialize and compare:
// var libString = serialize(lib);
// var newLib = deserialize(libString);
// assert(newLib.string() == "Paper:MyPaper,Book:MyBook");
NOTE: The main usage of de/serialization (at least in my case) is for moving complex objects to distant computers. For example, I want to build a big Library on my computer, then serialize it, put on a file, send the file to another computer, deserialize it there, and have the exact same Library.
You need to extend JSON semantics. If I were you, I would to something like this:
var protos = {}, //hash of prototypes
base = { //base prototype
toJSON: function () {
var props = {}; //properties to be serialized
for (var prop in this) { //this can be custimized, like taking `attrs` hash or something
if (this.hasOwnProperty(prop)) props[prop] = this[prop];
}
props.$proto = this.$proto; //need to copy this manually since it's not an `own propery`
return props;
}
};
function Paper(name) {
this.name = name;
}
protos.paper = Paper.prototype = Object.create(base);
Paper.prototype.$proto = 'paper';
Paper.prototype.toString = function() {
return 'Paper: ' + this.name;
}
function Book(name) {
this.name = name;
}
protos.book = Book.prototype = Object.create(base);
Book.prototype.$proto = 'book';
Book.prototype.toString = function() {
return 'Book: ' + this.name;
}
function Library(name) {
this.items = [];
}
Library.prototype = {
add: function(item) { this.items.push(item); },
toString: function () {
var titles = this.items.map(function(item) {
return item.toString();
});
return titles.join(',');
},
toJSON: function () {
return this.items.map(function(item) { return item.toJSON()});
}
};
Library.fromJSON = function (json) {
return json.map(function(item) {
var object = Object.create(protos[item.$proto]);
for (var prop in item) object[prop] = item[prop];
return object;
});
};
//test
var lib = new Library();
lib.add(new Paper('MyPaper'));
lib.add(new Book('MyBook'));
console.log(lib.toString());
var json = JSON.stringify(lib.toJSON());
console.log(Library.fromJSON(JSON.parse(json)).toString());
Here is a fiddle: http://jsfiddle.net/cSTT5/
I want to build a big Library on my computer, then serialize it, put on a file, send the file to another computer, deserialize it there, and have the exact same Library.
I've made an npm module named esserializer to solve this problem: save JavaScript class instance values recursively during serialization, in plain JSON format, together with its class name information. Then, during the deserialization stage, esserializer can recursively deserialize object instance, with all types/functions information retained, using the same class definition.
For your scenario, the code is pretty simple. It works if the serialized string is taken to another computer, as long as the same class definition exists on that machine:
const ESSerializer = require('esserializer');
// Paper class:
function Paper(name) {
this.name = name;
}
Paper.prototype = {
string: function() { return "Paper:"+this.name; }
};
Paper.prototype.constructor = Paper; // We need to redefine the constructor of Paper's prototype.
// Book class:
function Book(name) {
this.name = name;
}
Book.prototype = {
string: function() { return "Book:"+this.name; }
};
Book.prototype.constructor = Book;
// Library class:
function Library(name) {
this.items = [];
}
Library.prototype = {
add: function(item) { this.items.push(item); },
string: function () {
var titles = this.items.map(function(item) { return item.string(); });
return titles.join(",");
},
};
Library.prototype.constructor = Library;
///// Define a library:
var lib = new Library();
lib.add(new Paper("MyPaper"));
lib.add(new Book("MyBook"));
// assert(lib.string() == "Paper:MyPaper,Book:MyBook");
var serializedString = ESSerializer.serialize(lib);
// Later, on another machine, deserializedObj is a perfect copy of "lib":
var deserializedObj = ESSerializer.deserialize(serializedString, [Library, Book, Paper]);
console.log(deserializedObj.string()); // Paper:MyPaper,Book:MyBook

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

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, {})

Resources