Export class and instanciate it immediately on import - node.js

I have a ES6 class in NodeJS 4 :
vehicule.js
"use strict";
class Vehicule {
constructor(color) {
this.color = color;
}
}
module.exports = Vehicule;
When I need to instanciate in another file, I find myself doing this :
var _Vehicule = require("./vehicule.js");
var Vehicule = new _Vehicule();
I'm new to nodeJs, is there a way to do this in one line, or at least in a more readable way ?

A class is really supposed to be reused for many objects. So you should require the class itself:
var Vehicule = require("./vehicule.js");
and then create objects from it:
var vehicle1 = new Vehicule('some data here');
var vehicle2 = new Vehicule('other data here');
Usually classes start with an upper case letter, and instances of classes (objects themselves) with a lower case one.
If you want a "class" for just one objects, you can just create an inline object:
var vehicle = {
myProperty: 'something'
};
module.exports = vehicle;
//in some other file
var vehicle = require('vehicle');
Though if you really, really want to do that in one line, you can do:
var vehicle = new (require('vehicle'))('some constructor data here');
But that is not recommended. Pretty much ever.

If you really want to do this in one line:
var Vehicule = new (require('./vehicule'))('red');
but personally i would prefer two lines for the same reasons mentioned by #ralh.

Related

How do I test a function that is in a class with Jest

I have a function that is in a class :
Simplified version :
export class Button {
getAttributes(el) {
//random code that was removed for simplicity
return dataAttrs;
}
}
I was wondering how do I test this in Jest.
Here is what worked for me :
test('get attributes on element', () => {
let button= new Button();
var element = document.createElement('a');
element.setAttribute('href', 'https://www.google.ca/');
element.innerHTML = 'Test';
expect(breadcrumb.getAttributes(element)).toBe('Hello');
});
if there is simple class like the one that u define u can do:
it('We can check the class constructor', () => {
const classObject = new classObject();
expect(classObject ).toHaveBeenCalledTimes(1);
});
and use whatever the methods that Jest have.
But if there are complex classes and methods that ones are dependent from others i suggest you to read this and you can automatize it or can do it manually, mock the dependences and test it out.

Revert variables inside a Loop in Node JS

I am trying one logic in Node JS code which looks something like below:-
var startPersons1 = JSON.parse(JSON.stringify(persons1));
var startPersons2 = JSON.parse(JSON.stringify(persons2));
var startPersons3 = JSON.parse(JSON.stringify(persons3));
var startPersons4 = JSON.parse(JSON.stringify(persons4));
.....
// Operations on persons1, persons2, persons3, persons4 which are changed in methods called here
....
// Now persons1, persons2, persons3, persons4 are modified
// Now, if I wanted persons1, persons2, persons3, persons4 to come to their original state above, ie.
// startPersons1, startPersons2, startPersons3, startPersons4, I am doing something like this
persons1 = JSON.parse(JSON.stringify(startPersons1));
persons2 = JSON.parse(JSON.stringify(startPersons2));
persons3 = JSON.parse(JSON.stringify(startPersons3));
persons4 = JSON.parse(JSON.stringify(startPersons4));
You can assume this is inside some for loop.
So, is there a better way to do this revert everytime. The number of variables can increase by lot.
if persons1, persons2 etc are inside an array, you could use map function
var persons = [/*array of persons*/]
var newpersons = persons.map(function(person) {
/*change here your person object and return it.*/
return person
})
/*here persons is the originalone, newpersone is the new version*/

Actionscript - Dynamically assigning imported objects

Take this simplified code
import assets.panels.About1;
import assets.panels.About2;
import assets.panels.About3;
private var _panel:*;
_panel = new About1();
It is possible to define About1 as a variable, so I can set something like
var aboutPanel = 'About3';
So code executed would be
_panel = new About3();
To do that you can use flash.utils.getDefinitionByName like this :
var class_name:String = 'MyClass';
var my_class:Class = flash.utils.getDefinitionByName(class_name) as Class;
trace(my_class); // gives : [class MyClass]
var obj = new my_class();
addChild(obj);
trace(obj); // gives : [object MyClass]
Hope that can help.

Sharing & modifying a variable between multiple files node.js

main.js
var count = 1;
// psuedocode
// if (words typed begins with #add)
require('./add.js');
// if (words typed begins with #remove)
require('./remove.js');
// if (words typed begins with #total)
require('./total.js');
module.exports.count = count;
total.js
var count = require('./main.js').count;
console.log(count);
add.js
var count = require('./main.js').count;
count += 10;
console.log(count);
remove.js
var count = require('./main.js').count;
count -= 10;
console.log(count);
console.log
1
11
-9
Background:
I have an application (irc bot), and I want to add a feature that peeps can do #add 1 or #remove 1. I have a main.js that then requires different files depending on the triggers that are said. So add would trigger the add.js file, and that would then require('main.js') and add 10 (10 for simplification, it'll actually parse the number and use that number) to it. The problem I'm having is when someone goes about and does #remove. It require('main.js') and subtracts 10 from 1 resulting in -9. And doing #total would output 1.
I've done a fairly good search for module.exports and I haven't come across an example like the one i listed above. The docs don't include any examples close to what I'm wanting to do; and these questions 1, 2 I understand--but aren't of any usefulness to me--as I understand what's being said there.
Question:
I'd like to have both #add and #remove manipulate the same variable ( count ), and for #total to return the total of count with the #add and #removes taken into account. Am I using module.exports incorrectly; or is there a common way that variables are shared, with one file being able to modify the contents of the module.exports and returning the results to the main.js file?
Your problem is that when you do var count = require('./main.js').count;, you get a copy of that number, not a reference. Changing count does not change the "source".
However, you should have the files export functions. Requiring a file will only run it the first time, but after that it's cached and does not re-run. see docs
Suggestion #1:
// main.js
var count = 1;
var add = require('./add.js');
count = add(count);
// add.js
module.exports = function add(count) {
return count+10;
}
#2:
var count = 1;
var add = function() {
count += 10;
}
add();
#3: Personally i would create a counter module (this is a single instance, but you can easily make it a "class"):
// main.js
var counter = require('./counter.js');
counter.add();
console.log(counter.count);
// counter.js
var Counter = module.exports = {
count: 1,
add: function() {
Counter.count += 10;
},
remove: function() {
Counter.count += 10;
}
}
Not sure if this new or not but you can indeed share variables between files as such:
main.js
exports.main = {
facebook: null
};
counter.js
var jamie = require('./main');
console.info(jamie); //{facebook: null}
jamie.main.facebook = false;
console.info(jamie); //{facebook: false}
anothercheck.js
var jamie = require('./main');
console.info(jamie); //{facebook: null} //values aren't updated when importing from the same file.
jamie.main.facebook = true;
console.info(jamie); //{facebook: true}
Now you can share between files.
I know I'm a little bit late to answer this questions, just 7yrs!
You can simply use a global variable:
global.myVar = 'my-val';
console.log(myVar); // returns 'my-val'
// from here on it's accessable to all modules by just the variable name
using-global-variables-in-node-js
I have same problem like you,.. Sometimes I'd like to sharing variables between multiple files because I love modular style eg. separating controller, function, models in different folders/files on my node.js script so I can easy manage the code.
I don't know if this is the best solution but I hope will suit your needs.
models/data.js
// exports empty array
module.exports = [];
controllers/somecontroller.js
var myVar = require('../models/data');
myVar.push({name: 'Alex', age: 20});
console.log(myVar);
// [{ name: 'Alex', age: 20 }]
controllers/anotherController.js
var myVar = require('../models/data');
console.log(myVar);
// This array has value set from somecontroller.js before...
// [{ name: 'Alex', age: 20 }]
// Put new value to array
myVar.push({name: 'John', age: 17});
console.log(myVar);
// Value will be added to an array
// [{ name: 'Alex', age: 20 }, { name: 'John', age: 17}]
There is no way you can share a reference between different files. You shouldn't be.
I have a main.js that then requires different files depending on the triggers that are said
I don't think that's a good idea. All require statements you'll ever need must be at the top of the file.
I also see that You're requiring main.js in total.js and total.js in main.js. The require() function imports the module.exports of the file and assigns it to the namespace you provide. Your code shouldn't be split into files this way. You extract code into separate files only when they're modules by themselves. And if you do, you wouldn't be importing 2 files on each other.
It is also good to note that in javascript, when you assign something to a namespace, It gets copied (cloned) if it's a primitive. If it's an object, both namespaces then refer to the same object
var num = 5;
var prim = num;
prim++; // prim is 6, but num is still 5.
var num = {five:5};
var ob = num;
ob.five = 6;
console.log(num.five) //also 6.
A little hack that works but isn't recommended is using the process variable. You can apply different properties to it and essentially use them like you would the window object in browser-based JS. This little hack will provide a reference to the variable. It can be changed and manipulated and the change will carry over to all files that are required.
But do note that it is not recommended as overriding the process variable could have some unexpected effects and is subject to loss of information should another process interfere.
file1.js:
const s1 = require('./file2');
process.num = 2;
console.log("file1", process.num);
s1.changeNum();
console.log("file1", process.num);
file2.js:
module.exports.changeNum = () => {
process.num = 3;
console.log("file2", process.num);
};
output:
file1 2
file2 3
file1 3
alternatively, to all other answers
getters & setters
var _variableThing = 1223
module.exports = {
get variableThing(){
return _variableThing
},
set variableThing(val){
_variableThing = val
}
}
won't work with direct imports though

Node.js: Require locals

What I want
Is it possible to pass locals to a required module?
For example:
// in main.js
var words = { a: 'hello', b:'world'};
require('module.js', words);
// in module.js
console.log(words.a + ' ' + words.b) // --> Hello World
I'm asking this because in PHP when you require or include, the file which includes another files inherits it's variables, which is very useful in some cases, and I would be happy if this could be done in node.js too.
What I have tried and didn't worked
var words = { a: 'hello', b:'world'};
require('module.js', words);
var words = { a: 'hello', b:'world'};
require('module.js');
Both of these gives ReferenceError: words is not defined when words is called in module.js
So is it possible at all without global variables?
What you want to do is export it with an argument so you can pass it the variable.
module.js
module.exports = function(words){
console.log(words.a + ' ' + words.b);
};
main.js
var words = { a: 'hello', b:'world'};
// Pass the words object to module
require('module')(words);
You can also chop off the .js in the require :)
The question is: What do you want to achieve?
If you want to export just a static function you can use the answer from tehlulz. If you want to store an object inside the exports property and benefit from the require-caching node.js provides a (dirty) approach would be to you globals. I guess this is what you have tried.
Using JavaScript in a Web-Browser context you can use the window object to store global values. Node provides only one object that is global for all modules: the process object:
main.js
process.mysettings = { a : 5, b : 6};
var mod = require(mymod);
mymod.js
module.exports = { a : process.mysettings.a, b : process.mysettings.b, c : 7};
Alternatively if you are not interested in the exports caching you could do something like that:
main.js
var obj = require(mymod)(5,6);
mymod.js
module.exports = function(a,b){
return { a : a, b : b, c : 7, d : function(){return "whatever";}};
};

Resources