Node.js Inheritance - node.js

I have inherited a class from another JS, and added few prototype function over Parent functions. When i create a new instance of child, i want to call the constructor of parent. Please suggest a way.
Parent
function Parent() { .. }
Parent.prototype.fn1 = function(){};
exports.create = function() {
return (new Parent());
};
Child
var parent = require('parent');
Child.prototype = frisby.create();
function Child() { .. }
Child.prototype.fn2 = function(){};
exports.create = function() {
return (new Child());
};

You can use module util. Look simple example:
var util = require('util');
function Parent(foo) {
console.log('Constructor: -> foo: ' + foo);
}
Parent.prototype.init = function (bar) {
console.log('Init: Parent -> bar: ' + bar);
};
function Child(foo) {
Child.super_.apply(this, arguments);
console.log('Constructor: Child');
}
util.inherits(Child, Parent);
Child.prototype.init = function () {
Child.super_.prototype.init.apply(this, arguments);
console.log('Init: Child');
};
var ch = new Child('it`s foo!');
ch.init('it`s init!');

First of all, do not export create method, export constructor (Child, Parent). Then you will be able to call parent's constructor on child:
var c = new Child;
Parent.apply(c);
About inheritance. In node you can use util.inherits method, which will setup inheritance and setup link to superclass. If you don't need link to superclass or just want to inherit manually, use proto:
Child.prototype.__proto__ = Parent.prototype;

Parent (parent.js)
function Parent() {
}
Parent.prototype.fn1 = function() {}
exports.Parent = Parent;
Child
var Parent = require('parent').Parent,
util = require('util');
function Child() {
Parent.constructor.apply(this);
}
util.inherits(Child, Parent);
Child.prototype.fn2 = function() {}

Related

How to export object from module.exports?

I need to require a file passing a parameter, for this I used the following syntax:
module.exports = function(bot) {
const menu = new TelegrafInlineMenu(bot);
return menu;
};
the problem's that the code above export the function, I need to return the menu object, is there a way to do this?
I require the script using:
const menu = require('menu')(bot);
problem's that menu is a function not an object
function TelegrafInlineMenu(bot) {
// constructor
if (!(this instanceof TelegrafInlineMenu)) {
return new TelegrafInlineMenu(bot);
}
}
TelegrafInlineMenu.prototype.someFunction = function () {
// etc.
};
module.exports = TelegrafInlineMenu;

Arrow function use that is assigned by a module.export object cannot correctly resolve this

It seems that only if I fill out the child object directly in the Base function that is the only way that the getSettings function can see the this.name property correctly, but I was trying to have my objects in different files to avoid having one large file.
***child.js***
module.exports : {
getSettings: ()=>{
return this.name === 'foobar'
}
}
***base.js***
var Child = require('./child.js')
function Base(){
this.name = 'foobar'
this.child = Child
this.child2 = {}
for (var prop in Child){
this.child2[prop] = Child[prop]
}
this.child3 = {
getSettings: ()=>{
return this.name === 'foobar'
}
}
}
***index.js****
var Base = require('./base.js')
var b = new Base()
b.child.getSettings() //FAILS BECAUSE this.name is undefined
b.child2.getSettings() //FAILS BECAUSE this.name is undefined
b.child3.getSettings() //PASSES. this.name is defined
It's conventional in JS OOP to refer class instance as this, so it's semantically incorrect for child objects to refer to parent object as this. This also makes it difficult to work with an object like child that doesn't get desirable context as lexical this (like child3 does).
child object likely should be a class that are injected with parent instance as a dependency.
module.exports = class Child(parent) {
constructor(parent) {
this.parent = parent;
}
getSettings() {
return this.parent.name === 'foobar'
}
}
var Child = require('./child.js')
function Base(){
this.name = 'foobar'
this.child = new Child(this);
...
}

passing function to a class in nodejs

I have a function that I need to pass to a class I have defined in nodeJs.
The use case scenario is I want to give the implementer of the class the control of what to do with the data received from createCall function. I don't mind if the method becomes a member function of the class. Any help would be appreciated.
//Function to pass. Defined by the person using the class in their project.
var someFunction = function(data){
console.log(data)
}
//And I have a class i.e. the library.
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall(){
var result = new Promise (function(resolve,reject) {
resolve(callApi());
});
//doesn't work. Keeps saying notificationHandler is not a function
result.then(function(resp) {
this.notificationHandler(resp);
}) ;
//I want to pass this resp back to the function I had passed in the
// constructor.
//How do I achieve this.
}
callApi(){ ...somecode... }
}
// The user creates an object of the class like this
var obj = new A("abc#gmail.com", someFunction);
obj.createCall(); // This call should execute the logic inside someFunction after the resp is received.
Arrow functions (if your Node version supports them) are convenient here:
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall() {
var result = new Promise(resolve => {
// we're fine here, `this` is the current A instance
resolve(this.callApi());
});
result.then(resp => {
this.notificationHandler(resp);
});
}
callApi() {
// Some code here...
}
}
Inside arrow functions, this refers to the context that defined such functions, in our case the current instance of A. The old school way (ECMA 5) would be:
createCall() {
// save current instance in a variable for further use
// inside callback functions
var self = this;
var result = new Promise(function(resolve) {
// here `this` is completely irrelevant;
// we need to use `self`
resolve(self.callApi());
});
result.then(function(resp) {
self.notificationHandler(resp);
});
}
Check here for details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

Jasmine : Spying on a function call of another module

I have the following code structure :
const finalCall = require('./final.js');
function Func(){
this.process = {
initCall: function(params, callback){
let proParams;
//processing...
return finalCall(proParams, callback);
}
}
}
Now I need to test if my initCall function correctly processes the params and makes call to finalCall. I need to know how do I create a spy on my finalCall function, so when it gets called, I can track the proParams.
I have tried something like :
const func = new Func();
let proParams = null;
spyOn(func.process.initCall, "finalCall").and.callFake(function(pParams, callback){
proParams = pParams;
});
let params = { };
func.process.initCall(params, null);
expect(func.process.initCall.finalCall).toHaveBeenCalled();
expect(proParams).toEqual('...');
I am missing on what object I can access finalCall, or if there is another way to do so. Thanks in advance.
Finally I found a workaround to my problem. I created a prototype of the function finalCall() in my constructor Const, and put a spyOn on its object.
Solution
Main module:
const finalCall = require('./final.js');
function Func(){
const self = this;
this.process = {
initCall: function(params, callback){
let proParams;
//processing...
return self.finalCall(proParams, callback);
}
}
}
Func.prototype = finalCall;
and in my Spec file:
const func = new Func();
let proParams = null;
spyOn(const, finalCall);
let params = { };
func.process.initCall(params, null);
expect(func.finalCall).toHaveBeenCalled();

How to add event ability to object instance in Node?

It's ok to add event ability to a constructor:
function Stream() {
events.EventEmitter.call(this);
}
util.inherits(Stream, events.EventEmitter);
But how to add event ability to an object instance? The following code doesn't work:
var foo = {x: 1, y: 2};
util.inherits(foo, event.EventEmitter);
events.EventEmitter.call(foo);
After running the above code, foo.on still be undefined.
Is there a way to inherit or mix-in EventEmitter's content?
You can use the npm module node.extend.
It is a port of jQuery's $.extend and with it, you can do this:
var extend = require('node.extend'),
events = require('events');
extend(foo, events.EventEmitter.prototype);
or, if you don't want to use another module, you can use this:
function extend(target) {
var sources = Array.prototype.slice.call(arguments, 1);
return sources.forEach(function (source) {
Object.keys(source).forEach(function (key) {
target[key] = source[key];
});
}), target;
}
var events = require('events');
var foo = {x: 1, y: 2};
extend(foo, events.EventEmitter.prototype);

Resources