2

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?

6
  • I think @tymeJV is right. The net result should be the same, though mine is deferred until you actually call the function. Maybe the issue lies within the obj.config.defineProperty(Object.prototype, 'setDatastore' Commented Jan 6, 2016 at 14:03
  • console.log(g.alpha) and see what you get. Commented Jan 6, 2016 at 14:05
  • I get Object {metaType: "alpha", data: Object, in: Array[0], true: Array[0], false: Array[0], config: function Object() …} Commented Jan 6, 2016 at 14:07
  • can you please try changing 'config': Object to 'config': new Object() in your getNode() function Commented Jan 6, 2016 at 14:20
  • @eithedog I get the following error Uncaught TypeError: obj.config.defineProperty is not a function Commented Jan 6, 2016 at 14:22

1 Answer 1

1

Take a look at Object.defineProperty():

Object.defineProperty(obj, prop, descriptor)

Parameters

obj The object on which to define the property.

prop The name of the property to be defined or modified.

descriptor The 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']);

Sign up to request clarification or add additional context in comments.

11 Comments

I had similar implementation before, it conflicted with jQuery. I will try this again .
That's what I thought, but OP's code still works somehow (by works, I mean - with yours, and with OP's code, the 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?
Yep, I define setDatastore in couple of objects.
@eithedog Yes, that is correct. Adding a property to Object.prototype will make it accessable for all Objects, and that's not what we want to do here.
@Fawzan - with your code, you're actually defining different methods on 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
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.