Multiple export classes from same require(jsfile) - javascript

I'm currently designing an application and have some classes I'm extending. Below is a brief sample code of how it looks today, as well as where I want to go (aka one file, multiple classes and export them + consume them in main.js - or any other)..
TODAY
main.js
const UrgentTask = require('./urgentTask');
const Task = require('./task');
var ut = new UrgentTask({ name: "Some task", priority: "URGENT" });
var nt = new Task({ name: "Normal task" });
console.log(ut.toString());
console.log(nt.toString());
task.js
'use strict'
class Task {
constructor(data) {
this.name = data.name;
this.completed = false;
}
complete() {
console.log('completing task: ' + this.name);
this.completed = true;
}
save() {
console.log('Saving task: ' + this.name);
}
toString() {
return this.name + ' ' + this.completed;
}
}
module.exports = Task;
urgentTask.js
'use strict'
var Task = require('./task');
// Decorate "TASK"
class UrgentTask extends Task {
constructor(data) {
super(data);
this.priority = data.priority;
}
toString() {
return `[${this.priority}] ${super.toString()}`;
}
}
module.exports = UrgentTask;
WHAT I WOULD LIKE
main.js
const { Task, UrgentTask } = require('./task');
var ut = new UrgentTask({ name: "Some task", priority: "URGENT" });
var nt = new Task({ name: "Normal task" });
console.log(ut.toString());
console.log(nt.toString());
task.js
=> this would ideally export the two classes, but I don't know how to?
What I already tried:
module.exports = Task;
module.exports = UrgentTask;
But this blows up in node.

WHAT I WOULD LIKE
const { Task, UrgentTask } = require('./task');
That's a destructuring assignment, which assigns object properties to discrete bindings (constants, in this case).
So you need to export an object:
ES2015+ syntax (but using Node modules, not ES2015 modules):
module.exports = {Task, UrgentTask};
ES5 and earlier syntax:
module.exports = {Task: Task, UrgentTask: UrgentTask};
Actually, by default, exports already is an object so you can also do this:
module.exports.Task = Task;
module.exports.UrgentTask = UrgentTask;
But replacing it with a new object is fine too.
Simple non-Require example:
function getMyStuff() {
class Task { }
class UrgentTask extends Task { }
return {Task, UrgentTask};
}
const {Task, UrgentTask} = getMyStuff();
const ut = new UrgentTask();
console.log(ut instanceof UrgentTask); // true
console.log(ut instanceof Task); // true
NodeJS example:
mymodule.js:
class Task { }
class UrgentTask extends Task { }
module.exports = {Task, UrgentTask};
myapp.js:
const {Task, UrgentTask} = require("./mymodule.js");
const ut = new UrgentTask();
console.log(ut instanceof UrgentTask); // true
console.log(ut instanceof Task); // true

Related

Add prototype of a fuction

I have some question about my node.js project.
What I'm trying to do is, add additional functionality to a function.
So, I added new functionality using prototype, but it failed.
Below is my current code.
[ someFeatures.js ]
const functionFoo = new Function()
const functionBar = new Function()
module.exports = { functionFoo, functionBar }
[ addFeatures.js ]
// Import fuction
const { functionFoo, functionBar } = require('./someFeatures.js')
// Add additional feature
functionFoo.prototype.addtionalFeatureA = foo => {
return someFunction(foo)
}
// Add additional feature
functionBar.prototype.addtionalFeatureB = foo => {
return someOtherFunction(foo)
}
module.exports = { functionFoo, functionBar }
[ Other files will use this feature ]
const { functionFoo } = require('./someFeatures.js')
const aaa = new functionFoo()
aaa.addtionalFeatureA('bbb')
The result is 'TypeError: Cannot read properties of undefined (reading 'prototype')'
Is there any solution to fix this issue? Thanks in advance!
change new Function
into empty function
let yourFunction = function () {}
and change this
function.prototype.additional = foo => { ... }
to this
function.prototype.additional = function (foo) {
...
}

Class inheritance testing with mocha: getting 'ReferenceError: config is not defined' for one class but not another

I am testing inheritance between two classes in js and running into errors with one class but not another. Here is the two classes and the tests I am running starting with the two classes followed by the two tests:
class BuildingModel{
constructor(city, lastInspect){
this._city = city;
this._lastInspect = lastInspect;
}
get city() {
return this._city;
}
get lastInspect() {
return this._lastInspect;
}
}
module.exports = {BuildingModel};
const { BuildingModel } = require('./building');
class House extends BuildingModel{
constructor(sqFt, address, price) {
super(city, lastInspect)
this._sqFt = sqFt
this._address = address
this._price = price
}
,
get price() {
return this._price
}
get address() {
return this._address
}
get sqFt() {
return this._sqFt
}
get city(){
return this._city
}
get lastInspect(){
return this._lastInspect
}
}
module.exports = { 'House' : House,
'BuildingModel' : BuildingModel}
const assert = require('assert');
const chai = require('chai');
const { BuildingModel } = require('../building');
const expect = chai.expect;
const assertEq = assert.deepStrictEqual
describe('Building', function () {
describe('#constructor', function () {
it('Building construction working!', function () {
const city = "Fruita"
const lastInspect = 1994
const building = new BuildingModel(city, lastInspect)
assertEq(building.city, city)
assertEq(building.lastInspect, lastInspect)
});
it('End of building test', function () {
// ....
});
});
});
const assert = require('assert');
const chai = require('chai');
const { House } = require('../house');
const expect = chai.expect;
const assertEq = assert.deepStrictEqual
describe('House', function() {
describe('#constructor', function() {
it('Houses construction working!', function(){
const price = 120000
const address = "123 Lane"
const sqFt = 1200
const house = new House(sqFt, address, price, city, lastInspect)
assertEq(house.price, price)
assertEq(house.address,address)
assertEq(house.sqFt,sqFt)
});
it('End of house test', function(){
// ....
});
});
});
I think I am really close but this is the test result I am getting:
Building
#constructor
√ Building construction working!
√ End of building test
House
#constructor
1) Houses construction working!
√ End of house test
3 passing (11ms)
1 failing
House
#constructor
Houses construction working!:
ReferenceError: config is not defined
at new House (house.js:5:15)
at Context. (test\housetest.js:14:23)
at processImmediate (internal/timers.js:461:21)
npm ERR! Test failed. See above for more details.
Any help in showing me what I am doing wrong would be greatly appreciated. Thank you.

Catching an event from an a class which inherits EventEmitter using es6 classes

I'm new to Javascript and es6. I am attempting to catch an event emitted by an object which is an ecmascript-6 (es6) class called LaserHandler, that inherits EventEmitter. My listener is present in an object which is also an es6 class object called QRMarker, that instantiates the object. This is on nodejs not browser is used.
I expect to see the callback function of the of the listener to be called. The listener is not fired. There is no indication of error.
So I tried various alternate coding approaches including 1) using the 'event-emitter-es6' npm module. 2) rewriting to use const events = require('events').EventEmitter and extending events. 3) Varying the location of the listeners, emits, and where the class is instantiated.
The result of console.log (qrMarker): In the following code is:
QRMarker {
domain: null,
_events:
{ stationId: [ [Function: listener], [Function] ],
'*': [Function] },
_eventsCount: 2,
_maxListeners: undefined,
id: undefined }
const EventEmitter = require('event-emitter-es6');
/LaserHandler.js/
let qrMarker;
module.exports = class LaserHandler extends EventEmitter {
constructor(s, l) {
super();
logger = l;
socket = s;
qrMarker = new QRMaker(this.logger);
}
manageLaser() {
qrMarker.communication(socket);
socket.on ('LaserDown', () => {
console.log('LaserHandler.manageLaser: received event'
)});
qrMarker.on('stationId', (data) => {console.log(data)} );
qrMarker.on('*', (data) => {console.log ('Caught event !!!')});
}
}
/*end of file*/
/* QRMarker.js */
module.exports = class QRMarker extends EventEmitter {
constructor(l, id) {
super();
logger = l;
this.id = id;
}
communication(s) {
let connected = false;
let socket = s;
let dataBuffer;
let lastStatusCode;
this.emit( 'stationId', stationId);
dataBuffer = Buffer.from(data);
connected = true;
}
}
}
/* end of file */
/* LaserService */
module.exports = class LaserService {
constructor () {
}
startNeworking () {
server = net.createServer();
server.on('connection', function (socket) {
let laserHandler = new LaserHandler(socket, logger);
laserHandler.manageLaser();
});
server.listen(41020, function () {});
}
}
/*end of file */
/*TestLaserService -- this file is executed from node */
var LaserService = require("../LaserService.js");
let laserService = new LaserService(2);
laserService.startNeworking();
/* end of file*/
Thank you.

Expose multiple objects through module with constructor in nodejs

I created a module in nodejs where I wish to expose it's constants too. But this particular module contains a dependency which is provided at construction time i.e. dependency injection.
this is module1
const STORE_TYPE = {
STORE1: 1,
STORE2: 2
};
function service(dependency1) {
this.dep = dependency1;
}
service.prototype.doSomething = function(param1, store) {
if (STORE_TYPE.STORE1 == store) {
return this.dep.get(param1);
} else {
return "something";
}
};
module.exports = service;
I'm using module1 here:
var dep = require('./dep');
var dep1 = new otherService(dep);
var service = require('./service')(dep1);
function getData() {
return service.doSomething(id, /*this is module1 constant*/1);
}
How do I refere to module1's constants if module1 has a constructor.
I don't wish to add separate method only to create service since callee needs to perform multiple steps.
Try this:
service.js
exports.STORE_TYPE = {
STORE1: 1,
STORE2: 2
};
exports.service = function service(dependency1) {
this.dep = dependency1;
}
service.prototype.doSomething = function(param1, store) {
if (STORE_TYPE.STORE1 == store) {
return this.dep.get(param1);
} else {
return "something";
}
};
Using that module
app.js
const service = require('./service').service;
const STORE_STYLE = require('./service').STORE_TYPE;

node.js object extended with a mixin can't find function after instantiation

I've managed to get a fairly complex setup (though that's a question for Code Review) for my mixins that looks like this:
TooManyCaps.js
module.exports = {
labelCopyCaps: () => {
if (this.release.tracks.length > 1) {
if (_this._notEnoughLowercase(this.release.title)) {
this._recordError(release, 'LABELCOPYCAPS');
} else {
this.release.tracks.some( (track) => {
if (this._lowerCaseCount(track.label_copy)) {
this._recordError(release, 'LABELCOPYCAPS');
return true;
}
});
}
}
},
_notEnoughLowercase: (str) => {
if ((str.match(/[a-zA-Z]/g)||[]).length > 3
&& str.length - str.replace(/[a-z]/g, '').length) {
return true;
}
return false;
}
};
I then have an Object that would use this as a mixin:
Rule.js
class Rule {
constructor(release) {
this.release = release;
this.errors = [];
}
_recordError(error, options) {
this.errors.push({
release_id: this.release.id,
rule: error,
options: options,
});
}
}
module.exports = Rule;
i then have an index page that joins them together
index.js
const TooManyCaps = require('./TooManyCaps');
const Rule = require('./Rule');
Object.assign(Rule.prototype, [TooManyCaps]);
module.exports = Rule;
And then my main start of the program that does some instantiating of things:
'use strict';
const RuleValidator = require('./job/validation/RuleValidatorMixin');
const Rule = require('./job/validation/rulesmixins/rules/index');
// some logic that's a loop
arr.forEach((value) => {
new RuleValidator(new Rule(value)).validate();
}
and within validate() I have:
validate() {
console.log('VALIDATE');
this.rule.labelCopyCaps();
// console.log(this.rule);
}
But then when I run this, I get:
this.rule.labelCopyCaps is not a function
So where have i gone wrong?
Object.assign does not take an array:
Object.assign(Rule.prototype, [TooManyCaps]);
// ^ ^
should be just
Object.assign(Rule.prototype, TooManyCaps);

Categories