I have an initialized object that I initialized in app.js file and I would like to make this initialized object is available in all modules. How could I do that? Passing this object to every modules is one way to do and I'm wondering if I'm missing anything or there should be done in difference ways?
I saw mongoose actually support default connection, which I need to init in app.js one time and anywhere in other modules, I can just simply use it without requiring passing it around. Is there any I can do the same like this?
I also checked global object doc from node.js http://nodejs.org/api/globals.html, and wondering I should use global for issue.
Thanks
A little advice:
You should only very rarely need to use a global. If you think you need one, you probably don't.
Singletons are usually an anti-pattern in Node.js, but sometimes (logging, config) they will get the job done just fine.
Passing something around is sometimes a useful and worthwhile pattern.
Here's an example of how you might use a singleton for logging:
lib/logger.js
var bunyan = require('bunyan'),
mixIn = require('mout/object/mixIn'),
// add some default options here...
defaults = {},
// singleton
logger,
createLogger = function createLogger(options) {
var opts;
if (logger) {
return logger;
}
opts = mixIn({}, defaults, options);
logger = bunyan.createLogger(opts);
return logger;
};
module.exports = createLogger;
lib/module.js
var logger = require('./logger.js'),
log = logger();
log.info('Something happened.');
Hope that helps.
The solution, as you suggest is to add the object as a property to the global object. However, I would recommend against doing this and placing the object in its own module that is required from every other module that needs it. You will gain benefits later on in several ways. For one, it is always explicit where this object comes from and where it is initialized. You will never have a situation where you try to use the object before it is initialized (assuming that the module that defines it also initializes it). Also, this will help make your code more testable,
There are multiple solutions to the problem, depends upon how large your application is. The two solutions that you have mentioned are the most obvious ones. I would rather go for the third which is based on re-architecturing your code. The solution that I am providing looks alot like the executor pattern.
First create actions which require your common module that are in this particular form -
var Action_One = function(commonItems) {
this.commonItems = commonItems;
};
Action_One.prototype.execute = function() {
//..blah blah
//Your action specific code
};
var Action_Two = function(commonItems) {
this.commonItems = commonItems;
};
Action_Two.prototype.execute = function() {
//..blah blah
//Your action_two specific code
};
Now create an action initializer which will programmatically initialize your actions like this -
var ActionInitializer = function(commonItems) {
this.commonItems = commonItems;
};
ActionInitializer.prototype.init = function(Action) {
var obj = new Action(this.commonItems);
return obj;
};
Next step is to create an action executor -
//You can create a more complex executor using `Async` lib or something else
var Executor = function(ActionInitializer, commonItems) {
this.initializer = new ActionInitializer(commonItems);
this.actions = [];
};
//Use this to add an action to the executor
Executor.prototype.add = function(action) {
var result = this.initializer.init(action);
this.actions.push(result);
};
//Executes all the actions
Executor.prototype.executeAll = function() {
var result = [];
for (var i = this.action.length - 1; i >= 0; i--) {
result[i] = this.action[i].execute();
}
this.action = []
return result;
};
The idea was to decouple every module so that there is only one module Executor in this case which is dependent on the common properties. Now lets see how it would work -
var commonProperties = {a:1, b:2};
//Pass the action initilizer class and the common property object to just this one module
var e = new Executor(ActionInitializer, commonProperties);
e.add(Action_One);
e.add(Action_Two);
e.executeAll();
console.log(e.results);
This way your program will be cleaner and more scalable. Shoot questions if it's not clear. Happy coding!
Related
I am trying to find best way how to create multiple instances and configure my module according Module pattern.
Currently I have
var Logger = (function () {
// Private members
var _settings = {
json: JSON,
output: console
};
// Private methods
var _log = function (info) {
_settings.output.log(info);
};
var _dump = function (info) {
_log(_settings.json.stringify(info));
};
// Change default settings
var changeSettings = function (settingsArgs) {
if (settingsArgs !== undefined) {
if (settingsArgs.json !== undefined) {
_settings.json = settingsArgs.json;
}
if (settingsArgs.output !== undefined) {
_settings.output = settingsArgs.output;
}
}
};
return {
init: changeSettings,
log: _log,
dump: _dump
};
})();
I have several questions about this pattern.
What is the best way to provide configuration to the module, I simply created setter for private settings fields, but I feel this is not the best way it can be implemented. Please suggest right approach.
How to create multiple instances of my module. As I understood, module commonly used to encapsulate global objects and logic (like singletons), so most of time only one instances of module exists, but I need to have multiple instances. In my case this can be useful for example, I can create one logger ConsoleLogger another one will be AlertLogger the difference is output, but now I can only have one instance.
Please suggest the right way to follow, I have already read a lot of articles but haven't found answers to my questions. Thanks
What you have there is Module used as an Immediately-Invoked-Function-Expressions (IIFE), because of () at the end. Therefor, you are creating instance at class definition time and you can only have a single instance. You could clone one instance and have multiple of them, but that is not a good thing to do.
If you want to have multiple instances, you should remove IIFE expression at the end. Also, you can pass settings as constructor param:
var Logger = function (settingsArgs) {};
Now, you can create multiple instances:
var consoleLogger = new Logger({output: console});
var alertLogger = new Logger({output: alert}); // change this line probably, for this to work _settings.output.log(info);
Oh hi,
I saw some interesting posts about this subject but I think it's a really personal question that needs a customized answer. So I'm asking you what is the best way to organize my code for a Javascript plugin that need to be the more unobstructiv posible.
So my code looks like that :
var myApp = (function(){
//here are my global methods or variables
var self = this;
return {
method1:function(){}
method2:function(){}
method3:function(){}
}
})() || (myApp = {})
myApp.method1();
I execute the method1 that calls or use the entire code of my app.
I think i could add and onload event with addEventListener method to execute this method1, and i guess my code could have a better organisation.
I want to precise that my plugin is a bit small, like 200 lanes of javascript code, and it must be in Vanilla js. It's used on a single page in a website, no need to do a prototype class called with "new", in my opinion.
It really depends on your project and what you're trying to obtain.
There are several patterns that help you organize and maintain your code better.
I for one use a combination of patterns that I've made myself comfortable with among the years.
Here's my boilerplate for a module of my application :
;(function(global, udnefined){
var app = global.app || {},
moduleName = 'util',
module = app[moduleName] || {};
// "private" vars
var version = "1.2";
// fake "private" members (the udnerscore naming convention)
module._bindEventHandlers = function(){
// code here
// for chainability purposes
return this;
}
// "public" method
module.someMethod = function(){
// for chainability purposes
return this;
}
// "public" method
module.someOtherMethod = function(){
// for chainability purposes
return this;
}
// the init method
module.init = function(){
this
._bindEventHandlers()
.someMethod();
}
app[moduleName] = module;
global.app = app;
})(this);
And then, in your app (in the app initialization or whenever you actually need the module) you can simply call :
app.util.init();
app.util.someOtherMethod();
The provided module is highly reusable for creating new modules, because most modules should have an initialization logic (the init method), most of them would listen to some events (be it dom or custom events) - the _bindEventHandlers method - and it doesn't pollute the global namespace with variables (it just adds an object to the main app).
i use somthing the lines of this. all depenting on what i need to get done
(function(app, undefined){
var module = app.module = (function(){
var privatestuff
return {}
}())
var singelton = app.singleton = (function(){
var Module = function(){}
module.prototype.method1 = function(){}
return new Module()
}())
var ModulePrototype = app.ModulePrototype = function(){
var Module = function(){}
module.prototype.method1 = function(){}
return Module
}
}(myApp = window.myApp ||{}))
I've got a browser addon I've been maintaining for 5 years, and I'd like to share some common code between the Firefox and Chrome versions.
I decided to go with the Javascript Module Pattern, and I'm running into a problem with, for example, loading browser-specific preferences, saving data, and other browser-dependent stuff.
What I'd like to do is have the shared code reference virtual, overrideable methods that could be implemented in the derived, browser-specific submodules.
Here's a quick example of what I've got so far, that I've tried in the Firebug console, using the Tight Augmentation method from the article I referenced:
var core = (function(core)
{
// PRIVATE METHODS
var over = function(){ return "core"; };
var foo = function() {
console.log(over());
};
// PUBLIC METHODS
core.over = over;
core.foo = foo;
return core;
}(core = core || {}));
var ff_specific = (function(base)
{
var old_over = base.over;
base.over = function() { return "ff_specific"; };
return base;
}(core));
core.foo();
ff_specific.foo();
Unfortunately, both calls to foo() seem to print "core", so I think I've got a fundamental misunderstanding of something.
Essentially, I'm wanting to be able to call:
get_preference(key)
set_preference(key, value)
load_data(key)
save_data(key, value)
and have each browser do their own thing. Is this possible? Is there a better way to do it?
In javascript functions have "lexical scope". This means that functions create their environment - scope when they are defined, not when they are executed. That's why you can't substitute "over" function later:
var over = function(){ return "core"; };
var foo = function() {
console.log(over());
};
//this closure over "over" function cannot be changed later
Furthermore you are "saying" that "over" should be private method of "core" and "ff_specific" should somehow extend "core" and change it (in this case the private method which is not intended to be overridden by design)
you never override your call to foo in the ff_specific code, and it refers directly to the private function over() (which never gets overridden), not to the function core.over() (which does).
The way to solve it based on your use case is to change the call to over() to be a call to core.over().
That said, you're really confusing yourself by reusing the names of things so much, imo. Maybe that's just for the example code. I'm also not convinced that you need to pass in core to the base function (just to the children).
Thanks for your help. I'd forgotten I couldn't reassign closures after they were defined. I did figure out a solution.
Part of the problem was just blindly following the example code from the article, which meant that the anonymous function to build the module was being called immediately (the reusing of names Paul mentioned). Not being able to reassign closures, even ones that I specifically made public, meant I couldn't even later pass it an object that would have its own methods, then check for them.
Here's what I wound up doing, and appears to work very well:
var ff_prefs = (function(ff_prefs)
{
ff_prefs.foo = function() { return "ff_prefs browser specific"; };
return ff_prefs;
}({}));
var chrome_prefs = (function(chrome_prefs)
{
chrome_prefs.foo = function() { return "chrome_prefs browser specific"; };
return chrome_prefs;
}({}));
var test_module = function(extern)
{
var test_module = {};
var talk = function() {
if(extern.foo)
{
console.log(extern.foo());
}
else
{
console.log("No external function!");
}
};
test_module.talk = talk;
return test_module;
};
var test_module_ff = new test_module(ff_prefs);
var test_module_chrome = new test_module(chrome_prefs);
var test_module_none = new test_module({});
test_module_ff.talk();
test_module_chrome.talk();
test_module_none.talk();
Before, it was running itself, then when the extension started, it would call an init() function, which it can still do. It's just no longer an anonymous function.
I'm using the javascript module pattern, and have this so far:
var APP;
if(APP == undefined) {
APP = {};
}
APP = (function() {
var userId = -1;
var privateVar = '';
var _init = function($userId) {
userId = $userId;
};
var _publicMethod = function($id){
privateVar = id;
};
return {
init = function($userId) {
_init($userId);
},
publicMethod = function($id) {
_publicMethod($id);
}
};
})();
I then have a common utils module:
APP.utils = (function(){
})();
And then per page I am planning on having a module, so I don't wireup events (button clicks etc) for no reason on pages where these DOM elements don't event exist:
APP.homePage = (function(){
return {
};
})();
So each module will have a init() method that I will call on the page to run things that have to be run (e.g. wiring up events, setting variables like say userId etc):
$(document).ready(function() {
APP.init(<%= user.id %>);
APP.homePage.init('abc');
});
So now if the files get too big, I can break them out into separate files also.
What if one module needs to call another, I guess the only way for this to work is to do this via the public api right?
e.g. what if homePage needs userId, should I pass that in the homePage#init method?
How is my coding style, any obvious style that is not considered best practise?
Any comments on this approach? Is it good in general?
What if one module needs to call another, I guess the only way for this to work is to do this via the public api right?
Yes
e.g. what if homePage needs userId, should I pass that in the homePage#init method?
No. I'd not repeat the userId code in all modules, but offer a public getter for it in the default module.
Any comments on coding
This code
var APP;
if(APP == undefined) {
APP = {};
}
APP = ...
is quite useless. You don't need to check for object existance here, because you overwrite it anyway. That also means that this code must be the first to execute. If you want to make the modules independent from load order, you'd need to use something like
var APP = (function(a) {
var private_vars; // ...
a.init = ...
a.publicMethod = ... // add them to the object instead of creating new one
a.getPrivate = function() {
return private_vars;
};
return a;
})(APP || {}); // create one iff not already existing
// other file:
var APP = APP || {};
APP.utils = ... // add object to namespace
The code
var _publicMethod = function($id){
privateVar = id;
};
looks a bit odd. First, the underscore usually denotes a semiprivate (public-but-not-to-be-used) attribute of objects and should not be used for variable names. That's not the case in here as the function will be exposed as the "publicmethod" property of APP. Use the underscore there if you want it. Second, there is no need to use a function expression here. The code is in the module's local scope, and using a function declaration both makes it available everywhere in that scope and allows naming the function. You should use
function publicMethod($id) {
privateVar = id;
}
a.publicMethod = publicMethod;
The module pattern is, in my opinion, a really nice way to organize your code. To answer your questions:
1) Yes, your modules can only access methods and properties of other modules which have been exposed in the object they return.
2) I think your coding style looks pretty good. I'd make these changes:
APP = (function() {
var _userId = -1;
var _privateVar = '';
var init = function($userId) {
_userId = $userId;
};
var publicMethod = function($id){
_privateVar = id;
};
return {
init : init,
publicMethod : _publicMethod
};
})();
First, underscores are generally meant to denote "private" properties or methods. Secondly, you can do away with the extra functions in the object being returned and just point straight to the methods or properties you care about. This is generally referred to as the "Revealing Module Pattern", because even the public methods aren't defined within the returned object - they're simply referenced.
3) This approach is definitely a nice way to encapsulate code. You get the benefit of private and privileged methods, and you generally end up with a nicer API because you're only exposing things that need to be public.
Well done.
We are starting a new project and we have decided to use javascript ""namespaces"" to organize our client side code. The thing is that we have noticed that we can end very easily with super-long namespaces that are dificult to remember like
myProject.components.myComponent.doSomethig();
Is there any better way to do this or create some kind of "alias" somehow?
Thanks.
In JavaScript, you can make shortcut references to long namespaces stuff
var myComp = myProject.components.myComponent;
myComp.func1();
This is a reference only. You can do this with other long names and write less like this
var getEl = document.getElementById,
myEl = getEl('divId');
Also you can organize your code with RequireJS to organize your code
// file: myProject/components/myComponent.js
define(function(){
var myComponent ={};
myComponent.func1 = function(){
...
}
return myComponent;
});
// file: myProject/main.js
require(['myProject/components/myComponent', 'myProject/components/myComponent2'],
function(comp1, comp2){
var main = {};
main.init = function() {
...
comp1.func1();
}
});
// file: myProject/index.html
<script src="libs/require.js" data-main="myProject/main"></script>
If you use scoping functions around your module code (and if you don't, you should), then you can create local aliases quite easily as variables shared by all of the functions within a given module.
E.g., code defining the myComponent component:
(function() {
var comp = {};
// Export our component
myProject.components.myComponent = comp;
// add things to `comp`; since `comp` and `myProject.components.myComponent`
// refer to the same object, adding to `comp` is adding to the one object
// they both refer to and so you can access those things via either reference
})();
Similarly if you're writing app code that uses multiple components:
(function() {
var thisComp = myProject.components.thisComponent,
thatComp = myProject.components.thatComponent;
// Use `thisComp` and `thatComp`
})();
You can always store a subnamespace in a local variable:
var myComponent = myProject.components.myComponent;