Node JS : Requesting for code snippet explanation - node.js

I am just curious to know what is the purpose of,
function MyStream() {
events.EventEmitter.call(this);
}
in the following block of code taken from Nodejs.org Docs section,
var util = require("util");
var events = require("events");
function MyStream() {
events.EventEmitter.call(this);
}
util.inherits(MyStream, events.EventEmitter);
MyStream.prototype.write = function(data) {
this.emit("data", data);
}
var stream = new MyStream();
console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true
stream.on("data", function(data) {
console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"
Please explain.

This isn't the first time this question has been asked: https://groups.google.com/forum/#!topic/nodejs/ab_Xih1L5R8/discussion
Quote from Bradley Meck:
Using EventEmitter.call on an object will do the setup of instance methods / properties (not inherited) of an EventEmitter. It is similar in purpose to super(...) in Java or base(...) in C#, but it is not implicit in Javascript. Because of this, we must manually call it ourselves. As for the talk about util.inherits, this will make the MyStream function inherit from another prototyped function so that instanceof works (side note: javascript only allows single inheritance). Due to how the new operator works, if we have the this variable in a function set to an instanceof EventEmitter, and call EventEmitter.call it look for all intents and purposes as if EventEmitter's constructor is being called on our MyStream object.

Related

Subclassing, extending or wrapping Node.js 'request' module to enhance response

I'm trying to extend request in order to hijack and enhance its response and other 'body' params. In the end, I want to add some convenience methods for my API:
var myRequest = require('./myRequest');
myRequest.get(function(err, hijackedResponse, rows) {
console.log(hijackedResponse.metadata)
console.log(rows)
console.log(rows.first)
});
According to the Node docs on inherits, I thought I could make it work (and using the EventEmitter example in the docs works OK). I tried getting it to work using #Trott's suggestion but realized that for my use case it's probably not going to work:
// myRequest.js
var inherits = require('util').inherits;
var Request = require("request").Request;
function MyRequest(options) {
Request.call(this, options);
}
inherits(MyRequest, Request);
MyRequest.prototype.pet = function() {
console.log('purr')
}
module.exports = MyRequest;
I've been toying with extend as well, hoping that I could find a way to intercept request's onRequestResponse prototype method, but I'm drawing blanks:
var extend = require('extend'),
request = require("request")
function myResponse() {}
extend(myResponse, request)
// maybe some magic happens here?
module.exports = myResponse
Ended up with:
var extend = require('extend'),
Ok = require('objectkit').Ok
function MyResponse(response) {
var rows = Ok(response.body).getIfExists('rows');
extend(response, {
metadata: extend({}, response.body),
rows: rows
});
response.first = (function() {
return rows[0]
})();
response.last = (function() {
return rows[rows.length - 1] || rows[0]
})();
delete response.metadata.rows
return response;
}
module.exports = MyResponse
Keep in mind in this example, I cheated and wrote it all inside the .get() method. In my final wrapper module, I'm actually taking method as a parameter.
UPDATED to answer the edited question:
Here's a rough template for the contents of your myResponse.js. It only implements get(). But as a bare bones, this-is-how-this-sort-of-thing-can-be-done demo, I hope it gets you going.
var request = require('request');
var myRequest = {};
myRequest.get = function (callback) {
// hardcoding url for demo purposes only
// could easily get it as a function argument, config option, whatever...
request.get('http://www.google.com/', function (error, response, body) {
var rows = [];
// only checking error here but you might want to check the response code as well
if (!error) {
// mess with response here to add metadata. For example...
response.metadata = 'I am awesome';
// convert body to rows however you process that. I'm just hardcoding.
// maybe you'll use JSON.parse() or something.
rows = ['a', 'b', 'c'];
// You can add properties to the array if you want.
rows.first = 'I am first! a a a a';
}
// now fire the callback that the user sent you...
callback(error, response, rows);
});
};
module.exports = myRequest;
ORIGINAL answer:
Looking at the source code for the Request constructor, it requires an options object that in turn requires a uri property.
So you need to specify such an object as the second parameter in your call():
Request.call(this, {uri: 'http://localhost/'});
You likely don't want to hard code uri like that inside the constructor. You probably want the code to look something more like this:
function MyRequest(options) {
Request.call(this, options);
}
...
var myRequest = new MyRequest({uri: 'http://localhost/'});
For your code to work, you will also need to move util.inherits() above the declaration for MyRequest.prototype.pat(). It appears that util.inherits() clobbers any existing prototype methods of the first argument.

Passing a return from one function to another function that already has set parameters?

Edit: I know JS is asynchronous, I have looked over the How to Return thread. The issue I'm having is that going from "foo" examples to something specific = I'm not quite sure where to re-format this.
Also here is some context: https://github.com/sharkwheels/beanballs/blob/master/bean-to-osc-two.js
I have a question about returns in node. It might be a dumb question, but here goes. I have a function that connects to a socket, and gets OSC messages from processing:
var sock = dgram.createSocket("udp4", function(msg, rinfo) {
try {
// get at all that info being sent out from Processing.
//console.log(osc.fromBuffer(msg));
var getMsg = osc.fromBuffer(msg);
var isMsg = getMsg.args[0].value;
var isName = getMsg.args[1].value;
var isAdd = getMsg.address;
var isType = getMsg.oscType;
// make an array out of it
var isAll = [];
isAll.push(isName);
isAll.push(isMsg);
isAll.push(isAdd);
isAll.push(isType);
// return the array
console.log(isAll);
return isAll;
} catch (error) {
console.log(error);
}
});
Below I have the start of another function, to write some of that array to a BLE device. It needs name and characteristics from a different function. How do I get the below function to use isAll AND two existing parameters?
var writeToChars = function (name, characteristics) { // this is passing values from the BLE setup function
// i need to get isAll to here.
// eventually this will write some values from isAll into a scratch bank.
}
Thanks.
async call in this case be written something like this. state can be maintained in the variables in closure if required. In this particular case - you can do without any state (isAll) as well.
var isAll;
var soc = dgram.createSocket('udp4', oncreatesocket);
function oncreatesocket(msg, rinfo)
{
isAll = parseMessage(msg);
writeData(isAll);
}
function parseMessage(msg) {
...
// code to parse msg and return isAll
}
function writeData() {}
if the writeData is small enough function. It can be inside oncreatesocket without impacting the readability of the code.
Alright. So I figured out what to do, at least in this scenario. I'm sure there is a better way to do this, but for now, this works.
I'm mapping an existing global array of peripherals into the write function, while passing the OSC message to it as a parameter. This solved my issue of "how do I get two pieces of information to the same place". It figures out which peripheral is which and writes a different value to each scratch bank of each peripheral accordingly. Leaving here for future reference.
var writeToBean = function(passThrough){
var passThrough = passThrough;
console.log("in Write to bean: ", passThrough);
_.map(beanArray, function(n){
if(n.advertisement.localName === passThrough.name){
//var name = n.advertisement.localName;
n.discoverSomeServicesAndCharacteristics(['a495ff20c5b14b44b5121370f02d74de'], [scratchThr], function(error, services, characteristics){
var service = services[0];
var characteristic = characteristics[0];
var toSend = passThrough.msg;
console.log("service", service);
console.log("characteristic", characteristic);
if (toSend != null) {
characteristic.write(new Buffer([toSend]), false, function(error) {
if (error) { console.log(error); }
console.log("wrote " + toSend + " to scratch bank 3");
});
}
// not sure how to make the program resume, it stops here. No error, just stops processing.
});
}
});
}

What does events/EventEmitter do in a nodejs constructor function

I am learning node.js. On the nodejs api website there is a piece of code that I don't really get.
The link is here
var util = require("util");
var events = require("events");
function MyStream() {
events.EventEmitter.call(this);
}
util.inherits(MyStream, events.EventEmitter);
MyStream.prototype.write = function(data) {
this.emit("data", data);
}
var stream = new MyStream();
console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true
stream.on("data", function(data) {
console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"
so the confusing part is
events.EventEmitter.call(this);
What does it do here?
MyStream is a new object declaration that inherits behaviors from events.EventEmitter as can be seen from this line where the inheritance is configured:
util.inherits(MyStream, events.EventEmitter);
So, when the MyStream constructor is invoked usually via something like var stream = new MyStream();, it needs to also invoke the constructor of the object that it inherits from so the parent object can initialize itself properly. That's what this line is:
events.EventEmitter.call(this);
events.EventEmitter is the constructor of the object that MyStream inherits from. events.EventEmitter.call(this) instructs Javascript to call that constructor with the this pointer set to this object.
If you need more help with understanding .call(), you can read this MDN reference.

How to "subclass" a node.js module

I've been primarily a Perl coder for years, but also have a background in C++, so I'm coming from a "classical" OO background, and now learning node.js. I just read through The Principles of Object-Oriented JavaScript, which did a good job of explaining the JS concept of OO to classically-minded people like me. But I'm left with a question, specifically related to node.js and inheritance. Pardon me if I'm still using "classical" vocabulary to explain my problem.
Lets suppose I have a module lib/foo.js:
function foo() {
console.log('Foo was called');
}
module.exports.foo = foo;
And I want to "subclass" this in another module lib/bar.js:
var foo = require('foo.js');
// Do some magic here with *.prototype, maybe?
function bar() {
console.log('Bar was called');
}
module.exports.bar = bar;
Such that my main script can do this:
var bar = require('lib/bar.js');
bar.foo(); // Output "Foo was called"
bar.bar(); // Output "Bar was called"
Is this even possible? If so, what am I missing?
Or is this an anti-pattern? Or plain impossible? What should I do instead?
Here's how I did it, to override one method in the request module. Warning: many node modules are poorly designed for extension, including request, as they do way too much stuff in the constructor. Not just a gazillion argument options, but starting up IO, connections, etc. For example, request does the http connection (eventually) as part of the constructor. There is no explicit .call() or .goDoIt() method.
In my example, I wanted to use querystring instead of qs to format forms. My module is cleverly named "MyRequest". In a separate file named myrequest.js you have:
var Request = require('request/request.js');
var querystring = require('querystring');
MyRequest.prototype = Object.create(Request.prototype);
MyRequest.prototype.constructor = MyRequest;
// jury rig the constructor to do "just enough". Don't parse all the gazillion options
// In my case, all I wanted to patch was for a POST request
function MyRequest(options, callbackfn) {
"use strict";
if (callbackfn)
options.callback = callbackfn;
options.method = options.method || 'POST'; // used currently only for posts
Request.prototype.constructor.call(this, options);
// ^^^ this will trigger everything, including the actual http request (icky)
// so at this point you can't change anything more
}
// override form method to use querystring to do the stringify
MyRequest.prototype.form = function (form) {
"use strict";
if (form) {
this.setHeader('content-type', 'application/x-www-form-urlencoded; charset=utf-8');
this.body = querystring.stringify(form).toString('utf8');
// note that this.body and this.setHeader are fields/methods inherited from Request, not added in MyRequest.
return this;
}
else
return Request.prototype.form.apply(this, arguments);
};
Then, in your application, instead of
var Request = require("request");
Request(url, function(err, resp, body)
{
// do something here
});
you go
var MyRequest = require("lib/myrequest");
MyRequest(url, function(err, resp, body)
{
// do that same something here
});
I'm not a JavaScript guru so there may be better ways...
For reference, the specific solution I came up with to my sample code problem follows:
In lib/foo.js:
var Foo = function() {}
Foo.prototype.foo = function() {
console.log('Foo was called!');
};
module.exports = new Foo;
In lib/bar.js:
var foo = require('./foo.js');
var Bar = function() {}
Bar.prototype = Object.create(foo.__proto__);
Bar.prototype.constructor = Foo;
Bar.prototype.bar = function() {
console.log('Bar was called!');
};
module.exports = new Bar;
Then in my test script:
var bar = require('lib/bar.js');
bar.foo(); // Output "Foo was called"
bar.bar(); // Output "Bar was called"

Node.js sending an object with function definitions to worker thread

So I am working on a project in Node.js and I want to open up some extra threads to handle the processing load more efficiently. But I am using classes with function definitions with them and when I try to send those objects to the worker thread, the functions defined in the object disappear and I am only left with the other fields in the object. Is there a way to send the worker an object and preserve the functions so they can be called within the worker?
var cluster = require('cluster');
if(cluster.isMaster){
Monster = function(species){
this.attack = function(){
console.log('CHOMP');
};
this.name = species;
};
var vamp = new Monster('vampire'),
worker = cluster.fork();
worker.send({'monster' : vamp});
}
else{
process.on('message', function(msg) {
console.log(msg.monster); //this logs "{ name: 'vampire' }"
msg.monster.attack(); //TypeError: Object #<Object> has no method 'attack'
});
}
No, there is no way to pass functions between threads. You can pass only JS plain objects (data only) and handle it with functions defined in current thread (like create new object with received data).
Charlie, I realize you asked this question a year ago, but I was wanting to do something very similar and I came across your question which you didn't mark an answer to yet. I thought I would take a "stab" at it and show you what I have done with your code. This different way of organizing code is for me a very acceptable workaround in my node.js work. I am pretty sure this gives you a way to accomplish what you want, even though you can't do it in the manner you wanted.
Declare your "class" outside the cluster code, like this:
var cluster = require('cluster');
var Monster = function(species){
this.attack = function(){
console.log('CHOMP!');
};
this.die = function() {
console.log("Oh, what did I eat? I don't feel so good....\r\n");
process.exit(0);
};
this.scare = function() {
console.log("BOO! I am a " + this.name + "!");
};
this.name = species;
};
if(cluster.isMaster){
worker = cluster.fork();
worker.send({'species' : 'Vampire'});
}
else{
process.on('message', function(msg) {
if(typeof msg.species !== "undefined") {
myMonster = new Monster(msg.species);
myMonster.scare();
myMonster.attack();
myMonster.die();
}
});
}
Give that a whirl and see if this is an answer you can accept!
Ok, stumbled upon this answer, and I found it strange that no one brought this up, but it might be a more modern feature than the question:
eval
let str = "() => { console.log('test') }"
let func = eval(str)
func()
Think it's obvious what's going on here, you can parse any string to javascript, and you can send strings to workers, so you can build and object with functions:
let obj = { a: "() => { ... }" }
and send the object over. (JSON.stringify(obj) first, and than you will have to parse the object first, and than all the substrings seperately)

Resources