I have certain graph structure in my JS program where each node has specific functions associated to it.
Graph Structure
var g = {
"alpha_1" : getNode("alpha"),
"beta_1" : getNode("beta")
....
}
getNode() function
var getNode = function (type) {
var obj = {
'metaType': type,
'config': Object,
'data': {
'loc': {'x': '', 'y': ''},
'args': {'keys': [], 'values': []},
'return': []
},
'in': [],
'true': [],
'false': [],
'inLineId': [],
'outLineTrueId': [],
'outLineFalseId': []
//'prototype': Object.prototype
};
switch (type) {
case 'alpha':
obj.data.args.keys.push('dataStore', 'filters', 'limit', 'data');
obj.data.args.values['dataStore'] = '';
obj.data.args.values['limit'] = 'FALSE';
obj.data.args.values['data'] = 'FALSE';
obj.data.args.values['filters'] = [];
/**
* @param valueObj :{} JSON Object with fields from, value, type
*/
obj.config.defineProperty(Object.prototype, 'setDatastore', {
value: function (valueObj) {
obj.data.args.values['dataStore'] = valueObj;
},
enumerable: false,
configurable: true,
});
/**
* @param valuesArray :[] Array with fields from, value, type
*/
obj.config.defineProperty(Object.prototype, 'setReturnValues', {
value: function (valueArray) {
obj.data.args.values['return'].push.apply([], valueArray);
},
enumerable: false,
configurable: true,
});
case 'beta':
/**
* @param key
* @param op =/>=/!=/<=/</>
* @param valueObj :{} JSON Object with fields from, value, type
* @param next
*/
obj.config.defineProperty(Object.prototype, 'addFilter', {
value: function (key, op, valueObj, next) {
obj.data.args.values['filters'].push(
{
'key': key,
'op': op,
'value': valueObj,
'next': next
}
);
},
configurable: true,
enumerable: false
});
..
}
return obj;
}
Then I tried to access the defined functions in the following manner,
g.alpha.config.setDatastore({"a":"b"});
but it gives me an error.
Uncaught TypeError: g.alpha_1.config.setDatastore is not a function(...)
Can anyone help me to fix this?
1 Answer 1
Take a look at Object.defineProperty():
Object.defineProperty(obj, prop, descriptor)Parameters
objThe object on which to define the property.
propThe name of the property to be defined or modified.
descriptorThe descriptor for the property being defined or modified.
obj.config.defineProperty(Object.prototype, ...) will add the property to Object.prototype.
What you're looking for are: Object.defineProperty(obj.config, ...)
You also need to change 'config': Object, to 'config': new Object(),
var getNode = function(type) {
var obj = {
'metaType': type,
'config': new Object(),
'data': {
'loc': {
'x': '',
'y': ''
},
'args': {
'keys': [],
'values': []
},
'return': []
},
'in': [],
'true': [],
'false': [],
'inLineId': [],
'outLineTrueId': [],
'outLineFalseId': []
//'prototype': Object.prototype
};
switch (type) {
case 'alpha':
obj.data.args.keys.push('dataStore', 'filters', 'limit', 'data');
obj.data.args.values['dataStore'] = '';
obj.data.args.values['limit'] = 'FALSE';
obj.data.args.values['data'] = 'FALSE';
obj.data.args.values['filters'] = [];
/**
* @param valueObj :{} JSON Object with fields from, value, type
*/
Object.defineProperty(obj.config, 'setDatastore', {
value: function(valueObj) {
obj.data.args.values['dataStore'] = valueObj;
},
enumerable: false,
configurable: true,
});
/**
* @param valuesArray :[] Array with fields from, value, type
*/
Object.defineProperty(obj.config, 'setReturnValues', {
value: function(valueArray) {
obj.data.args.values['return'].push.apply([], valueArray);
},
enumerable: false,
configurable: true,
});
case 'beta':
/**
* @param key
* @param op =/>=/!=/<=/</>
* @param valueObj :{} JSON Object with fields from, value, type
* @param next
*/
Object.defineProperty(obj.config, 'addFilter', {
value: function(key, op, valueObj, next) {
obj.data.args.values['filters'].push({
'key': key,
'op': op,
'value': valueObj,
'next': next
});
},
configurable: true,
enumerable: false
});
}
return obj;
}
var g = {
"alpha_1": getNode("alpha"),
"alpha_2": getNode("alpha"),
"beta_1": getNode("beta")
}
g.alpha_1.config.setDatastore({
"a": "b"
});
g.alpha_2.config.setDatastore({
"a": "c"
});
//output
document.body.innerHTML = JSON.stringify(g.alpha_1.data.args.values['dataStore']);
document.body.innerHTML += "<br>" + JSON.stringify(g.alpha_2.data.args.values['dataStore']);
11 Comments
g.alpha_1.config has method setDatastore). I wonder if he's not defining setDatastore on all Objects instead of only on instance of obj.config object?setDatastore in couple of objects.Object.prototype will make it accessable for all Objects, and that's not what we want to do here.Object "class", depending upon which condition your code goes to. With @Johan Karlsson code you'll be defining methods on the instances of Object for each of your elements within g. edit: @Johan Karlsson - yeah, I've tried it out for myself ;) it was some time I've dabbled with the definerProperty and wasn't sure how it could have been working in OP's code
obj.config.defineProperty(Object.prototype, 'setDatastore'console.log(g.alpha)and see what you get.Object {metaType: "alpha", data: Object, in: Array[0], true: Array[0], false: Array[0], config: function Object() ...}'config': Objectto'config': new Object()in yourgetNode()functionUncaught TypeError: obj.config.defineProperty is not a function