How to avoid lots of if-else in javascript (nodejs) - javascript

Based on a parameter, function should select a json file out of more 100 json and fire a query to other system.
There will lots of query around in hundreds.
Obviously if else and switch won't be manageable. I took a look for strategy patten in the javascript.
var queryCode = req.param('queryCode');
if(queryCode == 'x'){
//do something
} else if( queryCode == 'y'){
//do something
} else if( queryCode == 'z') {
//do something
}
// do something might become large sometimes...
so I want to replace it something like strategy pattern. Which will be the best design.
Thanks in advance for any suggestion for this problem.

First of all, your concern is really good, if/else chains are evil.
When you have some different behaviors -maybe long, maybe unrelated- and you have to choose one in runtime based on some variable value, there is not sense in creating a great list of if else. That would be hard to maintain, introduces risks, most probably is also mixing responsibilities in the same class, adding new behaviors is dirty (can break old things and implies modify already tested classes, add new different responsibilities to an already working class) and many other reasons.
You was already correct mentioning the Strategy pattern. This will be the one that fits better your problem. You can also take a look at the Command Pattern but the general concept will be the same: encapsulate the different behaviors in separate classes.
Then you can use a Factory to retrieve the correct strategy to use.
In a nutshell, you will have a bunch of strategy classes, all implementing a method, lets say execute
//strategyA.js
function StrategyA(){
}
StrategyA.prototype = {
execute: function() {
//custom behavior here
}
}
module.exports = StrategyA;
//strategyB.js
function StrategyB(){
}
StrategyB.prototype = {
execute: function() {
//custom behavior here
}
}
module.exports = StrategyB;
Then you create the factory class, that create the correct class according to a parameter. The mapping value->class ideally would be on a confing file and then register it to the factory class, but for simplicity you can hardcode it in the same file. Something like this:
//factory.js
var StrategyA = require('./strategyA.js'),
StrategyB = require('./strategyB.js');
var _ = require('underscore');//asuming you have underscore
module.exports = function () {
var serviceDescriptions: [
{ name: 'a', service: StrategyA},
{name: 'b', service: StrategyB}
];
var getStrategy: function (name) {
//asuming you have underscore, otherwise, just iterate the array to look for the proper service
return _.find(this.serviceDescriptions, {name: name}).service;
};
}
With all this, starting is more complex, but specially if you have a lot of different strategies, or have to add more in the future, would be a good investment in the midterm. And your main code will be just something as simple as:
var Factory = require("factory.js");
...
var queryCode = req.param('queryCode');
var strategy = Factory.getStrategy(queryCode);
strategy.execute()
So, no matter how many different behaviors you have, or how long or complex or different they are, your main class will always look the same, simple and easy to follow.

Related

Alternatives to eval

My program processes many different types of documents to extract information from them.
It has a very generic structure to fit the hundreds of different types/formats of docs we use.
Processor Code :
Processor.prototype.process = function(){
var self = this;
var fields = self.processor_config;
var p = {};
for(key in fields){
if(fields.hasOwnProperty(key)){
p[key]=self._processKey(fields[key]);
if(typeof(p[key])=='undefined' || p[key]===''){
self.emit('warning', {
type: 'Problem parsing Key',
msg: 'Key : '+key,
doc: self.docName
});
}
}
}
self.emit('extracted',p);
};
The processKey() function then sorts out what to do based on the "type" field :
Productor.prototype._processKey = function(cnf) {
var self = this;
var value;
if(cnf.type=="css"){
value = self._processCSSKey(cnf);
}else if(cnf.type=="regexp"){
value = self._processRegexpKey(cnf);
}else if(cnf.type=="custom"){
value = self._processCustomKey(cnf);
}
return value;
};
Information on what to extract from each type of document comes from a mongodb collection :
Fictional config with 2 types of fields :
doc_name: "FormK7",
processor_config: {
company:{
type:"css"
selector:"p",
ord:3,
attr:{type:"text",parser:""}
},
litigation:{
type:"custom"
func:"(function(){var a =['123'];return a})()"
},
}
The example above is pretty useless, but the real thing has more complicated functions (not much though).
My custom processor looks like :
Productor.prototype._processCustomKey = function(cnf) {
var value = eval(cnf.func);
return value;
};
My problem is that I haven't found a way to process custom keys without using eval. And yet the simple mention of 'eval' brings to my mind pictures of an angry Douglas Crockford banishing me to a dark oblivion for all eternity...
Additional info :
In real life, the function stored in mongo is minified.
The generic processor is needed as having one processor per document type would be extremely wasteful (formats change all the time, there's hundreds of them and some are used once only...). So these functions need to be recorded in some way. And they are too different to be hardcoded...
There is no user input and the app is not accessible from the web. A malicious user would have access to the server before being able to inject code in mongo, so the security concern is extremely low.
So the question is the following :
Is eval really evil in this case, or is it a valid use case? Is there a better way/best practice to handle this?
You could create a module that exports from mongo to a temporal file and then use require to import that file. That way you wont be evaling and, like Bergi mentioned, it would prevent the scope problems that eval has.
Also, once you export it, and before requiring it, you could use something like Esprima to create an AST of the code and analyse it to see if it complies with some criteria you may have. (Like, perhaps, you could forbid the use of this in the code imported as a safety measure - thats part of the rules ADSafe has)

Sharing JS files across application

We're developing a mobile application and we're trying to figure out the best approach to share javascript functions across the application.
At the moment we have individual files that simply have:
var LIB = {
URL: "http://localhost/service",
connect: function() {
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
this._somethingElse();
},
_somethingElse: function() {
// do something else
}
};
Then we simply call things like:
LIB.connect(); or LIB.disconnect();
across any file.
This also gives us access to LIB.URL as well.
My question is whether this approach is the best?
I've seen people use the following approach as well, but to what benefit?
var LIB = function () {
this.URL = "http://localhost/service";
this.connect = function () {
var myself = this;
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
myself._somethingElse(); // best way to invoke a private function?
};
this._somethingElse = function () {
// do something else
};
};
This requires the following:
var lib = new LIB();
lib.connect();
EDIT:
I've also seen the following:
window.lib = (function () {
function Library () {
}
var lib = {
connect: function () {
// connect to server
}
};
return lib;
}());
I'm slightly confused with all these options.
It just depends on which you like better. I (on a personal level) prefer the former, but to each his own. The latter does have the disadvantage of requiring to either remember to declare the new before using it, or having to keep track of a already created one.
Additionally, on a technical level the first one should get slightly (as in, barely noticeable) performance, as you don't have to compute a new function.
Edit Yes, the first way is definitely the fastest.
I highly recommend going with a module system. Until ES6 comes along (http://wiki.ecmascript.org/doku.php?id=harmony:modules), you will have to use a 3rd party library in order to do this.
Each object/class/util/etc is a module.
A module exports a public api, whereas consuming modules import other modules by declaring their dependencies.
Two "standards" that exist: AMD and CommonJS. In the browser, a library like RequireJS, which uses the AMD standard, is very popular. I recommend checking out their site first: http://requirejs.org/ and see their examples.
The main advantage here is that you only expose the public api, which allows you to create a sandbox of your functionality. It's also more explicit as it's really easy to see what your module depends on, instead of relying on global objects.
There are several different approaches to structuring JavaScript code for re-usability. You can research these and decide which is best. Me personally, I have used the second approach that you've outlined. However, I separate my code into sections and actually adhere to an MVVM structure. So for instance, I have a name space called models and view models. Each of my js files begins with:
window.[APP NAME].Models.[CLASS/MODULE NAME] or window.[APP NAME].Models.[CLASS/MODULE NAME]
So, let's say I have a namespace called mynamespace and I have a module/class called myclass. My js file would begin with:
window.MYNAMESPACE = window.MYNAMESPACE || {};
window.MYNAMESPACE.ViewModels = window.MYNAMESPACE.ViewModels || {};
window.MYNAMESPACE.ViewModels.MyClass = function () {
// a public function
this.func1 = function () {
};
// a private function
function func2() {
}
};
I would then consume that class by calling:
var myClassModel = new window.MYNAMESPACE.ViewModels.MyClass();
myClassModel.func1();
This gives you some nice encapsulation of your code. Some of the other patterns you can research/google are: Prototype Pattern, Module Pattern, Revealing Module Pattern, and the Revealing Prototype Pattern.
I hope that helps but if you have any questions on what I've just said, feel free to comment on this post.

Faking/Mocking a Javascript object for Unit Tests

Quite a large portion of my work day to day involves working with Dynamics CRM and writing JS to extend the functionality on the forms.
Most clientside interaction in Dynamics involves using an object provided for you when the form loads, which is just Xrm. So you might have something like:
function OnLoad() {
Xrm.Page.getAttribute('name').setValue('Stackoverflow!');
var x = Xrm.Page.getAttribute('name').getValue();
}
I tend to write a wrapper for the Xrm object, mainly because it is a lot easier than remembering some of the chaining and end up with something like:
function WrappedXrm(realXrm) {
var xrm = realXrm;
this.getValue(name) {
return xrm.getAttribute(name).getValue();
}
}
//and then use it as so
var myXrm = new FakeXrm(Xrm);
var myXrmValue = myXrm.getValue('Name');
I am trying out QUnit and wondering how would I go about unit testing in this scenario?
Obviously the example above is a single line, it might not be worth testing it. But assume there was some business logic there that I wanted to test.
The only way I can see is doing some set up before each test along the lines of
var fakeXrm = {};
fakeXrm.Page = {};
fakeXrm.Page.getAttribute = function(name) {
var tempAttr = {};
tempAttr.getValue = function() {
return 'A fake value';
}
}
And then testing on 'A fake value' being returned, but this doesn't 'feel' right to me at all.
Where am I going wrong?
Using Mocks
So in this case, you want to create an instance of WrappedXrm, and pass it an object that mocks the Xrm from your lib ; you need a mock of Xrm.
A first alternative is to write it like you did (which is perfectly valid, if you know what the interface of Xrm is.)
Some libraries like sinon.js or "spies" in the jasmine framework can help you write code like ;
create a 'mock' Xrm, to configure what it should return
create an instance of WrappedXrm with this mock
call the getValue method of WrappedXrm
check that some method was called on the mock
But in the case of javascript, simply created a object that has just the right properties might be okay.
Note that your tests would break if the structure of the "real" Xrm object changes ; that might be what bother's you, but that's always the risk with mocks...
Using the real implementation
If you don't want to test against a mock (which might make sense in case of a wrapper), then maybe you can write the mimimal code that would create an actual Xrm object in your qunit html page (Maybe hardcoding markup ? I don't know the library, so...)
Hoping this helps.

Are there any dangers associated with using JavaScript namespaces?

Are there any dangers/caveats one should be aware of when creating JavaScript namespaces?
Our project is fairly expansive and we are running a lot of JavaScript files (20+, expecting more). It is impossible to have any code maintainability without using namespaces, so we are implementing them like so:
var namespace1 = {
doSomething: function() {
...
},
doSomethingElse: function() {
...
}
}
And then to create hierarchies, we link them like so:
var globalNamespace = {
functions1: namespace1,
functions2: namespace2,
...
}
This works fine, but it is essentially a "trick" to make JS behave as if it did have namespaces. Although this method gets used a lot, most literature on this seems to focus on how to do it, and not whether there are any possible drawbacks. As we write more JS code, this is quickly becoming an integral part of the way our system works. So it's important that it works seamlessly.
Were there any situations in which this "induced" namespace system caused you errors, or otherwise needed special attention? Can we safely expect identical behaviour across all browsers?
The way you define namespaces in your example it appears to create globals out of each namespace so you end up with
window.namespace1
window.namespace2
window.globalNamespace
window.globalNamespace.namespace1
window.globalNamespace.namespace2
So if you have anything that clobbers window.namespace1 it will also clobber window.globalNamespace.namespace1
edit:
Here's how we got around this problem:
namespacing = {
init: function(namespace) {
var spaces = [];
namespace.split('.').each(function(space) {
var curSpace = window,
i;
spaces.push(space);
for (i = 0; i < spaces.length; i++) {
if (typeof curSpace[spaces[i]] === 'undefined') {
curSpace[spaces[i]] = {};
}
curSpace = curSpace[spaces[i]];
}
});
}
};
Then you use it like this:
namespacing.init('globalNamespace.namespace1');
globalNamespace.namespace1.doSomething = function() { ... };
This way you don't have to introduce new global variables and you can confidently add to an existing namespace without clobbering other objects in it.
Since you are basically adding functions to objects and those objects into other objects, I would expect each browser to handle this the same way.
But if you want modularity, why not use a (relatively) simple framework like require.js? That will allow you and your team to write code in a modular fashion and allows the team to 'import' these modules where needed:
require(["helper/util"], function() {
//This function is called when scripts/helper/util.js is loaded.
});
Require.js will take care of dependencies, and it will also prevent polluting the global namespace.
We use a similar system at work and it does the job just fine. I don't see any drawbacks there could be; it's just objects and properties. For that same reason, cross browser compatibility should be good. You can end up having to write some long names to resolve to a particular function, like Foo.Bar.Test.Namespace2.Function, but even then that can be solved by assigning it to a variable before hand.
This is how I'd recommend doing it, so you stay out of the global scope entirely except for your "base" namespace. We do something similar where I work. Let's say you work for Acme co, and want ACME to be your base namespace.
At the top of every file, you'd include:
if (!window.ACME) { window.ACME = {} }
Then you just go and define whatever you want in terms of that.
ACME.Foo = {
bar: function () { console.log("baz"); }
}
If you want a deeper level of namespace, you just do the same thing for each level.
if (!window.ACME) { window.ACME = {} }
if (!ACME.Foo) { ACME.Foo = {} }
This way each file can be tested independently and they'll set up the namespace infrastructure automatically, but when you compile them together or if you test multiple files simultaneously, they won't keep overwriting things that are already defined.

Testing private functions in javascript

I'm using the module pattern in Javascript to separate my public interface from the private implementation. To simplify what I'm doing, my code generates a chart. The chart consists of multiple parts (axises, labels, plot, legend, etc.) My code looks like:
var Graph = function() {
var private_data;
function draw_legend() { ... }
function draw_plot() { ... }
function helper_func() { ... }
...
return {
add_data: function(data) {
private_data = data;
},
draw: function() {
draw_legend()
draw_plot()
}
}
}
Some people advocate only testing the public interface of your classes, which makes sense, but I'd really like to get in some tests to test each of the components separately. If I screw up my draw_legend() function, I'd like that test to fail, not a test for the public draw() function. Am I on the wrong track here?
I could separate each of the components in different classes, for example make a Legend class. But it seems silly to create a class for what's sometimes just 5-10 lines of code, and it would be uglier because I'd need to pass in a bunch of private state. And I wouldn't be able to test my helper functions. Should I do this anyway? Should I suck it up and only test the public draw()? Or is there some other solution?
There is no way to access inner functions (private) from an outer scope. If you want to test inner functions you might consider adding a public method for testing purposes only. If you are using some sort of a build environment, for example ant, you may pre-process the javascript file for production and remove those test functions.
Actually Javascript is an Object oriented language. It's just not a statitcally typed one.
My solution is just a little bit of hack. QUnit example:
At the top of Qunit test html I have declared:
var TEST_AVAILABLE = true;
In the testable class I have a fragment like this:
if(TEST_AVAILABLE){
this.test={
hasDraft:hasDraft,
isInterpIdIn:isInterpIdIn,
// other private methods
};
}
In the QUnit you could verify
test( "hello booth", function() {
var b = new Booth();
ok(b);
ok(b.test);
ok(!b.test.hasDraft());
});
I have a similar problem. The solution I came up with is not something I like but it does the job and there's not a better solution I can find.
function Graph()
{
this.Test = function _Test(expressionStr) { return eval(expressionStr); }
var private_data;
function draw_legend() { ... }
function draw_plot() { ... }
function helper_func() { ... }
...
}
To test:
var g = new Graph();
g.Test("helper_func()") == something;
g.Test("private_data") == something2
There is an easy way actually. You can use ajax to load the script and inject a function that exposes the private functions. I have an example here that uses qUnit and jQuery. But I'm sure the same can be easily accomplished using pure Javascript.
In an object oriented language, you would typically unit test the protected methods by having the test class inherit from the class it's testing.
Of course, Javascript is not really an object oriented language, and this pattern does not allow for inheritance.
I think you either need to make your methods public, or give up on unit testing them.
There is the only one right option: Different Builds for Testing and Production
1) mark development only parts
/* test-code */
api._foo = foo
/* end-test-code */
2) strip them later... ;)
grunt.registerTask("deploy",
[
"concat",
"strip-code",
...
#philwalton has written beautiful articles:
HOW: https://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/
WHY: https://philipwalton.com/articles/why-i-test-private-functions-in-javascript/

Categories