I have several objects that I want to store within an overarching configuration object. The individual objects have various properties in common. I'm used to a functional programming style in JavaScript, but can't figure out a DRY way to implement the storage of these objects in a global config object.
var config = {};
config['myKey'] = {
'key': 'myKey',
'name': 'My Key',
'icon': '<h1>Category One</h1>',
'filterFn': function(obj) {
// function unique to this obj
return obj;
},
'values': function() {
// function unique to this obj
return myData.filter(function(val) { return val['myKey']; };
}
}
Problems: repeats keys ('name', 'icon', etc.) for each object, necessitates changing myKey in a few different places
The config['myKey'] object assignment repeats for about 5 different objects. These objects have all of the same properties in common.
There are two noticeable "code smells" with this approach.
One is that I repeat the same property names 5 times (key, name, icon, etc.).
The second is that I have to repeat "myKey" each time I want to use
it in the object (e.g., in config['myKey']['key'] and
config['myKey']['values'].
I know that I could potentially create a function, for example createMyKeyObject() and if I passed in arguments. This would save the need to repeat the myKey in multiple places, thus solving the second problem. It would look as follows:
function getMyKey(key, name) {
var filterFn = function(obj) {
return obj;
};
var values = data.filter(function(val) { return val[key]; };
config.filters[key] = {
'key': key,
'name': name,
'icon': '<h1>Category One</h1>',
'filterFn': filterFn,
'values': values
};
}
getMyKey('myKey', 'My Key');
Problems: repeats keys ('name', 'icon', etc.) for each object, declaring object values in two separate places (function call, inside function), modifies global object inside function
This solves the second problem of repeating the key and the name, but creates new problems. One is that I'd be declaring values pertaining to the same object in two separate places (inside of the function and in the functional call). It's also a more verbose solution. And finally, it has the side-effect of modifying the global config object inside of the function.
Is there a proper solution that gets rid of these "code smells"? Can prototypical inheritance solve this in some way?
You can use a constructor, I don't see a need for inheritance
function Config(key, name, icon, values, filterFn) {
this.key = key;
this.name = name;
this.icon = icon;
this.values = values;
this.filterFn = filterFn;
}
var cfg = {};
// Don't want to repeat "someKey"? put it in a variable.
var myKey = 'someKey';
cfg[myKey] = new Config(myKey, 'someName', 'icon',
[1,2], function(obj){ return obj + myKey});
myKey = 'otherKey';
cfg[myKey] = new Config(myKey, 'anotherName', 'anotherIcon',
[3,4], function(obj){ return obj + '_' + myKey});
// Or create a method to help, may be overdoing it...
function addConfig(key, name, icon, values, filterFn) {
cfg[myKey] = new Config(key, name, icon, values, filterFn];
}
addConfig('someKey', 'thatName', 'thisIcon', [6,7], o => o);
In EcmaScript 6, you can save some typing
function Config(key, name, icon, values, filterFn) {
Object.assign(this, {key, name, icon, values, filterFn});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With