Suppose I have a MyViewModel like this:
// MyViewModel.js module
function MyViewModel() {
};
exports.MyViewModel = MyViewModel;
And main.js using it:
// main.js
var MyViewModel = require('./MyViewModel');
var vm = new MyViewModel.MyViewModel(); // akward
it's weird to have new MyViewModel.MyViewModel().
What's the best way to handle this?
Found the answer myself:
// MyViewModel.js module
module.exports = function MyViewModel() {
};
Related
My app.js contains:
var m1 = require("./m1");
m1.f1(...);
My m1.js contains:
var m1 = module.exports = {};
m1.f1 = function(...) { };
I would like to pass somevariable when loading m1 from app.js:
var m1 = require("./m1")(somevariable);
How can I write m1.js so that the function definition of m1.f1 can access somevariable?
If you want to be able to do this:
var m1 = require("./m1")(somevariable); // it is equivalent to var m = require("./m1"); and then m(someVariable); so m (the exports of the module m1.js) should be a function
then module.exports in m1.js should be a function:
// m1.js:
module.exports = function(theVariable) {
// use variable then return the following object:
return {
f1: function() { /* ... */ }
};
}
So now you can use the module in app.js like this:
// app.js:
var m1 = require("./m1")(someVariable);
m1.f1(/* ... */);
module.exports is the value that will be returned by the call to require when loading the module.
// app.js
require("./m1")(somevar);
// m1.js
module.exports = function(param) {
return "something";
}
The answer above by Ibrahim makes sense if you want to call m1 as a function. What it seems to me, though, is that your use case would be better served by using a JS class.
That way, you can import 'm1' the regular way with require('m1') and then create an instance of M1 with new m1(<whatever you want to pass in>);
Now when you want to call M1, just use m1.f1()
To support classes, your M1 should look something like:
export default class m1 {
constructor(param1, param2) {
this.param1 = param1;
this.param2 = param2;
}
f1() {
do whatever with params here
}
}
The biggest benefit of this is readability. Now when someone (or you) looks at your code, they will see where this input is coming from. Otherwise, it can be hard to track down where the params are coming from. Especially as your code gets more complex.
I'm having trouble with IntelliJ Idea's code completion and syntax checking and JavaScript.
I have the following (simplified) code for a Singleton object:
var MySingleton = new function() {
var self = this;
self.prop = "hello world";
self.printHello = function() {
console.log(self.prop);
};
};
MySingleton.printHello();
The problem is, that IntelliJ complains at the last line about Unresolved function or method printHello(). It also will not suggest printHello when autocompleting from MySingleton.. The code itself works fine though.
I guess I have to either annotate or rewrite my code in a different style. But how?
I am using factory to get Singeltons in Javascript.
var factory = function(){
this.singelton = null;
/**
* #return MySingleton
*/
function singelton(){
if(this.singelton==null){
this.singelton = new MySingelton();
}
return this.singleton;
}
}
var instance_of_my_singleton = factory.singelton();
It seems like the module pattern is close to what I want to do and is well supported by Idea's code indexing:
var MySingleton = (function () {
var self = this;
var prop = "hello world";
function printHello () {
console.log(self.prop);
};
// export public functions
return {
printHello: printHello
};
})();
MySingleton.printHello();
I have this js module (simplified example):
var dbLoader = require('dbLoader');
function MyModule() {
this.build(){
return dbLoader.load('yipee');
}
}
module.exports = MyModule;
How on earth do I spyOn(dbLoader,'load') ??
Because when I try I get the error
spyOn could not find an object to spy upon for load()
Any help much appreciated...
You probably should export them both:
module.exports.MyModule = MyModule;
module.exports.dbLoader = dbLoader;
The you can import them as follows:
var MyModule = require('my-module').MyModule;
var dbLoader = require('my-module').dbLoader;
I have a module like below
'use strict';
var val = GlobalVariable.someMethod();
...
...
module.exports = myExportedClass;
I am calling it with require('./myModule');. But would like to know if GlobalVariable can be dynamically injected.
I have tried this method, though I know that this does not work :)
(function(GlobalVariable) {
require('./myModule');
})(SomeOtherGlobalVariable);
So it did not, because module will execute in different scope. Is there any other way where I can pass my own version of GlobalVariable when using require.
Yes, it can be injected. Do something like the following:
module.exports = function(injectedObject) {
return {
doSomething: function() {
return injectedObject.something();
}
}
};
you can pass you variable as an argument when requiring it
yourvariable="value";
var file = require('./myModule')(yourvariable);
or can pass it separately, as file now contain function reference of module.exports
yourvariable="value";
var file = require('./myModule');
file(yourvariable)
your module will look like as:
module.exports = function(yourVaraible) {
yourVaraible.myfunction = function() {
};
return yourvariable;
};
Currently, I write node.js modules like this:
//MyModule.js
function MyModule() {
...somecode
}
MyModule.prototype.someFunc = function() {...}
module.exports = MyModule
However, when I need to use the module, I have to write something like this:
//main.js
var MyModule = require('MyModule');
var myModule = new MyModule();
This seems terribly ugly. Isn't there some way to do something like this
//main.js
var myModule = require('MyModule').new();
Am I doing something wrong?
quick hack for something not ugly
module.js
function MyModule() {
console.dir('constructor');
}
module.exports = MyModule;
app.js
Function.prototype.new = function () {
return new this();
};
var MyModule = require('./module.js').new(); // 'constructor'
If your module consists solely of functions, it may not need to be created as an instance - just define your module as being an object filled with functions. Like so:
var MyModule = {
prepareHtmlContent: function() {
},
autoLoadActionInitiatorFunctions: function() {
}
};
The reason I suggest this is that you've referred to your object as 'MyModule'. If your intent is specifically to use it as a 'Class', and instantiate separate copies of it when they're needed, then you're doing it the correct way.
Here is what I use
(function(module) {
module.myFunction = function() {
}
module.createSomeObj = function() {
return {
foo: 1,
bar: 'bar'
};
}
}(module.exports));
Usage
var myModule = require('./myModule');
myModule.myFunction();
var myObject = myModule.createSomeObj();