Require resolves undefined - javascript

I have the following class structure.
EmployeeService.js
const {EmployeeRequestExecutor} = require('./EmployeeRequestExecutor');
class EmployeeService {
fulfill(request){
EmployeeRequestExecutor.delegateEmployeeRequest(request);
}
}
module.exports = {EmployeeService};
EmployeeRequestExecutor.js
const {HelpfulEmployee} = require('./HelpfulEmployee');
class EmployeeRequestExecutor {
static delegateEmployeeRequest(request){
let employee = new HelpfulEmployee();
employee.work(request);
}
static executeEmployeeRequest(request){
console.log('Executed', request);
}
}
module.exports = {EmployeeRequestExecutor};
HelpfulEmployee.js
const {EmployeeRequestExecutor} = require('./EmployeeRequestExecutor');
class HelpfulEmployee {
work(request){
EmployeeRequestExecutor.executeEmployeeRequest(request);
}
}
module.exports = {HelpfulEmployee};
If we then do
let employeeService = new EmployeeService();
employeeService.fulfill(request);
we get
TypeError: Cannot read property 'executeEmployeeRequest' of undefined in HelpfulEmployee.js:5:33
Why is it so that with such call structure EmployeeRequestExecutor inside HelpfulEmployee.js is undefined?

There is a circular dependency between HelpfulEmployee and EmployeeRequestExecutor (they both require each other).
Circular dependencies result most of the time from class design issues. To fix them, you should reconsider the flow of information between your objects.
This is an option, but there are many more:
const {HelpfulEmployee} = require('./HelpfulEmployee');
class EmployeeRequestExecutor {
static delegateEmployeeRequest(request){
let employee = new HelpfulEmployee();
let requestExecutor = new EmployeeRequestExecutor();
employee.work(request, requestExecutor);
}
executeEmployeeRequest(request){
console.log('Executed', request);
}
}
module.exports = {EmployeeRequestExecutor};
class HelpfulEmployee {
work(request, requestExecutor){
requestExecutor.executeEmployeeRequest(request);
}
}
module.exports = {HelpfulEmployee};

Without getting into the final purpose of this architecture, to remove the circular dependency #Nicolas already mentioned, one option is to instantiate and provide the employee from the service to the executor as:
const { EmployeeRequestExecutor } = require("./EmployeeRequestExecutor");
const { HelpfulEmployee } = require("./HelpfulEmployee");
class EmployeeService {
fulfill(request) {
let employee = new HelpfulEmployee();
EmployeeRequestExecutor.delegateEmployeeRequest(employee, request);
}
}
module.exports = { EmployeeService };

Related

Is there a better way to implement a singleton pattern, using Node.js?

I'm working on a (pseudo) game engine to be used with Foundry.js. The intention was to create a scaffolding that can be reused to quickly create different game systems. To make the final product easier to read and troubleshoot, I decided to use Node.js and a very modular system. (I'm not sure if any more context is needed, but please ask if it is.)
Is there any obvious issue with my implementation?
Note: I'm an 2nd year medical student and self-taught over the past summer --> a lot of what I do might look weird so...
Note: the file and object names were removed, along with extemporaneous code. I added some fillers so that the general idea would still be conveyed
core file: singleton which contains all engine modules within its instance
const Module_A = requires('./modules/module_a.js');
const Module_B = requires('./modules/module_b.js')
module.exports = (function(){
var instance;
function createInstance(){
var o = Object.create({
Module_A: Module_A,
Module_B: Module_B,
// etc.
})
return o;
}
return {
getInstance: function(){
if(!instance){
instance = createInstance();
}
return instance;
},
Module_A: function(){
if(!instance){
instance = createInstance();
}
return instance.Module_A;
},
Module_B: function(){
if(!instan ce){
instance = createInstance();
}
return instance.Module_B;
}
};
}())
an abstract class declaration
module.exports = (
class {
constructor(){}
static getType = function(){
return entityConfig.type;
};
static entityConfig = {
type: 'Object.(Engine.Entity)'
}
}
);
a concrete class declaration
const Entity = requires('*./entity.js');
module.exports = (
class extends Entity {
static requiredParameters = () => {throw `incomplete code at ${new Error().lineNumber}`};
static optionalParameters = () => {throw `incomplete code at ${new Error().lineNumber}`};
static docData = () => {throw `incomplete code at ${new Error().lineNumber}`};
/* ------------------------------------ */
/* CONSTRUCTOR */
/* ------------------------------------ */
constructor(){
arguments.forEach(arg => {
if(!arg.includes(requiredParameters) && !arg.includes(optionalParameters)){
throw console.error(`ERROR: unknown token; ${arg}\n${docData}`);
}
});
this._data = args.data;
this.data = this._data;
}
}
);

How do you use the clone feature in gremlin javascript?

Trying to save and reuse a query- clone();
I have already tried query.clone(), clone(query), statics.clone(query), graphPredicate.clone(query)
reference: http://tinkerpop.apache.org/docs/current/recipes/#traversal-component-reuse
const { Graph } = gremlin.structure;
const { P: graphPredicate, statics } = gremlin.process;
const { _ } = gremlin.process.statics;
const g = graph.traversal().withRemote(gremlinConnection);
const query = statics.hasLabel(‘Movie’).hasId(gt(‘C’))
const count = g.V().flatMap(query.clone()).count().next()```
`Exception: TypeError: Cannot read property 'clone' of undefined`
There's no clone() in javascript. But you can easily create one:
function clone(traversal) {
return new gremlin.process.GraphTraversal(
traversal.graph,
traversal.traversalStrategies,
new gremlin.process.Bytecode(traversal.bytecode)
)
}
you can also add it to the traversal itself: http://tinkerpop.apache.org/docs/current/reference/#gremlin-javascript-dsl
class MyTraversal extends gremlin.process.GraphTraversal {
constructor(graph, traversalStrategies, bytecode) {
super(graph, traversalStrategies, bytecode)
}
clone() {
return new MyTraversal(
this.graph,
this.traversalStrategies,
new gremlin.process.Bytecode(this.bytecode)
)
}
}
class MyTraversalSource extends gremlin.process.GraphTraversalSource {
constructor(graph, strategies, bytecode) {
super(graph, strategies, bytecode, MyTraversalSource, MyTraversal)
}
}
const g = traversal(MyTraversalSource).withRemote(dc)

Is a Node.js module a singleton?

I used to implement singleton this way:
class MySomething {
constructor(props) {}
}
let myInstance = null;
module.exports = (props) => {
//first time call
if(props) {
myInstance = new MySomething (props);
return myInstance;
} else {
return myInstance;
}
this assumes that at app.js (entry file) I will call first:
require('./MySomething')(props)
then everywhere in the project I use:
const instanceOfSomething = require('./MySomething')();
I discovered that every time I got a new instance!
What's wrong in my code?
I tried also this way:
class MySomething {...}
const mySomething = (function() {
let myInstance = null;
return {
init: function() {
myInstance = new MySomething();
},
getInstance: function() {
return myInstance ;
}
}
})();
module.exports = mySomething;
and I got the some problem when importing this module from different files, anyone can explain to me?
every require of file create new instance of mySomething
UPDATE
I tried this example now:
class MySomething {...}
const mySomething = {
myInstance: null,
init: function() {
myInstance = new MySomething();
},
getInstance: function() {
return myInstance ;
}
}
};
module.exports = mySomething;
The same problem happened, maybe it is related to my project structure, I will explain it here:
the code below belongs to module "facts"
facts folder contains a folder named "dao" this folder contains MySomething.js (the singleton)
in the facts/index.js I have:
const Localstorage = require('./dao/MySomething');
exports.init = (path) => {
Localstorage.init(path)
}
exports.Localstorage = Localstorage;
Now in a folder named "core" which contains the "facts" folder I re-exported the Localstorage again in "index.js" like this:
const facstModule = require('./facts');
exports.Localstorage = facstModule.Localstorage;
Then in "schedule" folder which contains "Runtime.js" within I write:
const { Localstorage } = require('../core');
setTimeout(() => {
const localstorageIns = Localstorage.getInstance(); //this is always null!
}, 5000)
In app.js file (entry point) I did:
const facts = require('./src/facts');
facts.init(__dirname);
Normally instance will be created before the timeout execute the callaback,
But I noticed that there two instance of Localstorage which is singleton
the cleanest way to do a singleton is
class MyClass () { ... }
module.exports = new MyClass()
if you need a singleton that gets instantiated once, I would do:
class MyClass () { ... }
let myClass
const MyClassSingleton = (...args) => {
if (myClass) {
return myClass
}
myClass = new MyClass(...args)
return myClass
}
module.exports = MyClassSingleton
Every require of file create new instance of mySomething because every time you return new object with init method and getInstance method.
If you need singleton you need do like this:
class MySomething {
constructor() {
if (!MySomething.instance) {
MySomething.instance = this;
}
}
getInstance: function() {
return MySomething.instance;
}
}
module.exports = MySomething;
class Singleton {
constructor() {
this.my_obj;
}
static makeObject() {
if (!this.my_obj) {
this.my_obj = new Singleton();
}
return this.my_obj;
}
add() {
return 1
}
}
// so to get the object we need to call the makeobject method
const obj = Singleton.makeObject()
console.log(obj.add());

Setup testing with MobX store circular references

I am trying to figure out testing with Jest for my MobX stores.
I am using Mobx, React, and Jest.
class ConfigStore {
constructor(RootStore) {
this.rootStore = RootStore;
this.config = {};
}
}
class DataStore {
constructor(RootStore) {
this.config = RootStore.config;
}
}
class UIStore {
constructor(RootStore) {
this.config = RootStore.config;
this.data = RootStore.data;
}
}
class RootStore {
constructor() {
this.config = new ConfigStore(this);
this.ui = new UIStore(this);
this.data = new DataStore(this);
}
}
Did I set my stores up correctly?
If so, what is the best way to test the stores before they get passed to Provider?
Your question is very unclear. What exactly do you want to test about these stores in unit tests? You can't really test data itself.
My suggestions:
link to stores
instead of using setting a single property just keep the whole store:
class DataStore {
constructor(RootStore) {
this.configStore = RootStore;
}
}
this way you can besure properties are always properly updated and observed.
if you want you can always have property on your lower level stores:
class DataStore {
constructor(RootStore) {
this.configStore = RootStore;
}
get config() {
return this.configStore.config;
}
}
Abstract
if you use typescript abstract your stores with interfaces so the stores are way easilier tested:
class DataStore {
constructor(store: IConfigStore) {
this.configStore = store;
}
}
interface IConfigStore {
config: Config;
}
Use a repository pattern
For every store make a repository injectable so that all api calls done by the store are actually done in this repository:
class RootStore {
constructor(repository) {
this.repostiory = repository;
this.config = new ConfigStore(this);
this.ui = new UIStore(this);
this.data = new DataStore(this);
this.initializeData();
}
async initializeData(){
this.config = await this.repository.getConfig();
}
}
This way you can easily mock the repository to give static date so you dont need to do any api calls.
Keep your react components pure
The react components that you really want to unit test. make sure they dont use mobx stores directly but you use the inject() function instead to make a second class: https://github.com/mobxjs/mobx-react#inject-as-function
this way your components are way easilier testable and useable stand alone:
const PureReactComponent = ({ name }) => <h1>{name}</h1>
const SimpleMobxComponent = inject(stores => ({
name: stores.userStore.name
}))(PureReactComponent)
// usage:
render() {
return <SimpleMobxComponent/>
}

Converting Singleton JS objects to use ES6 classes

I'm using ES6 with the Webpack es6-transpiler per my article here: http://www.railsonmaui.com/blog/2014/10/02/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/
Does it make any sense to convert two Singleton objects to use ES6 Classes?
import { CHANGE_EVENT } from "../constants/Constants";
var EventEmitter = require('events').EventEmitter;
var merge = require('react/lib/merge');
var _flash = null;
var BaseStore = merge(EventEmitter.prototype, {
emitChange: function() {
this.emit(CHANGE_EVENT);
},
/**
* #param {function} callback
*/
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
/**
* #param {function} callback
*/
removeChangeListener: function(callback) {
this.removeListener(CHANGE_EVENT, callback);
},
getFlash: function() {
return _flash;
},
setFlash: function(flash) {
_flash = flash;
}
});
export { BaseStore };
This is file ManagerProducts.jsx that has a singleton that should extend from BaseStore.
/**
* Client side store of the manager_product resource
*/
import { BaseStore } from "./BaseStore";
import { AppDispatcher } from '../dispatcher/AppDispatcher';
import { ActionTypes } from '../constants/Constants';
import { WebAPIUtils } from '../utils/WebAPIUtils';
import { Util } from "../utils/Util";
var merge = require('react/lib/merge');
var _managerProducts = [];
var receiveAllDataError = function(action) {
console.log("receiveAllDataError %j", action);
WebAPIUtils.logAjaxError(action.xhr, action.status, action.err);
};
var ManagerProductStore = merge(BaseStore, {
getAll: function() {
return _managerProducts;
}
});
var receiveAllDataSuccess = function(action) {
_managerProducts = action.data.managerProducts;
//ManagerProductStore.setFlash({ message: "Manager Product data loaded"});
};
ManagerProductStore.dispatchToken = AppDispatcher.register(function(payload) {
var action = payload.action;
if (Util.blank(action.type)) { throw `Invalid action, payload ${JSON.stringify(payload)}`; }
switch(action.type) {
case ActionTypes.RECEIVE_ALL_DATA_SUCCESS:
receiveAllDataSuccess(action);
break;
case ActionTypes.RECEIVE_ALL_DATA_ERROR:
receiveAllDataError(action);
break;
default:
return true;
}
ManagerProductStore.emitChange();
return true;
});
export { ManagerProductStore };
No. Makes no sense.
Here's a really simple example of a singleton object in es6:
let appState = {};
export default appState;
If you really want to use a class in your singleton approach, I would recommend against using "static" as it more confusing than good for a singleton at least for JS and instead return the instance of the class as a singleton like so...
class SomeClassUsedOnlyAsASingleton {
// implementation
}
export default new SomeClassUsedOnlyAsASingleton();
This way you can still use all the class things you like that JavaScript offers but it will reduce the confusion as IMO static isn't fully supported in JavaScript classes anyway as it is in typed languages such as c# or Java as it only supports static methods unless you just fake it and attach them directly to a class (at the time of this writing).
I'd argue that singletons (classes that manage their own singleton lifetime) are unnecessary in any language. That is not to say that singleton lifetime is not useful, just that I prefer that something other than the class manage the lifetime of an object, like a DI container.
That being said, the singleton pattern CAN be applied to JavaScript classes, borrowing the "SingletonEnforcer" pattern that was used in ActionScript. I can see wanting to do something like this when porting an existing code base that uses singletons into ES6.
In this case, the idea is that you make a private (via an un exposed Symbol) static singleton instance, with a public static instance getter. You then restrict the constructor to something that has access to a special singletonEnforcer symbol that is not exposed outside of the module. That way, the constructor fails if anyone other than the singleton tries to "new" it up. It would look something like this:
const singleton = Symbol();
const singletonEnforcer = Symbol()
class SingletonTest {
constructor(enforcer) {
if(enforcer != singletonEnforcer) throw "Cannot construct singleton";
}
static get instance() {
if(!this[singleton]) {
this[singleton] = new SingletonTest(singletonEnforcer);
}
return this[singleton];
}
}
export default SingletonTest
Then you can use it like any other singleton:
import SingletonTest from 'singleton-test';
const instance = SingletonTest.instance;
I had to do the same so here is a simple and direct way of doing a singleton,
curtsy to singleton-classes-in-es6
(original link http://amanvirk.me/singleton-classes-in-es6/)
let instance = null;
class Cache{
constructor() {
if(!instance){
instance = this;
}
// to test whether we have singleton or not
this.time = new Date()
return instance;
}
}
let cache = new Cache()
console.log(cache.time);
setTimeout(function(){
let cache = new Cache();
console.log(cache.time);
},4000);
Both console.log calls should print the same cache.time (Singleton)
In order to create Singleton pattern use a single instance with ES6 classes;
'use strict';
import EventEmitter from 'events';
class Single extends EventEmitter {
constructor() {
this.state = {};
}
getState() {
return this.state;
}
}
export default let single = new Single();
Update: According to #Bergi explanation, below one is not a valid argument.
This works because of (refer to Steven)
> If I understand CommonJS + the browser implementations correctly, the
> output of a module is cached, so export default new MyClass() will
> result in something that behaves as a singleton (only a single
> instance of this class will ever exist per process/client depending on
> env it's running in).
You can find an example here ES6 Singleton.
Note: This pattern is using in Flux Dispacher
Flux: www.npmjs.com/package/flux
Dispacher Example: github.com/facebook/flux/blob/master/examples/flux-todomvc/js/dispatcher/AppDispatcher.js#L16
Singleton class
class SingletonClass {
constructor( name = "", age = 0 ) {
if ( !this.constructor.instance ) {
this.constructor.instance = this;
this.name = name;
this.age = age;
}
return this.constructor.instance;
}
getName() {
return this.name;
}
getAge() {
return this.age;
}
}
const instanceOne = new SingletonClass( "One", 25 );
const instanceTwo = new SingletonClass( "Two", 44 );
console.log( `Name of instanceOne is "${instanceOne.getName()}"` );
console.log( `Name of instanceTwo is "${instanceTwo.getName()}"` );

Categories

Resources