Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setters/Getters for a nested Object

I know how to set Custom Setters & Getters in Javascript using Object.defineProperty

My intention with the following code snippet is to be able to hit the setter function whenever a property nested value inside the globalProject object is modified.

var ClassA = function () {
    this.globalProject = {
        a: "DEFAULT VALUE",
        b: null
    };
    this.LastSavedProject = {};

};

Object.defineProperty(ClassA.prototype, 'globalProject', {
    get: function () {
        console.log("OVERRIDE");
        return this._flag;
    },
    set: function (val) {
        console.log("EDITING A DEEP VALUE")
        this._flag = val;
    },
});


var obj = new ClassA();

obj.globalProject.a = "HELLO WORLD" //Should get "EDITING A DEEP VALUE" in the console. 

I imagine what is happening is that the getter method is being called and returning a reference to an object I want to modify. Because of that the setter is never being called since I am modifying a reference to a nested value and not the property I have a setter on.

Can anyone help me sort out this issue? Here's a fiddle: http://jsfiddle.net/z7paqnza/

like image 676
user3583341 Avatar asked Mar 18 '23 17:03

user3583341


2 Answers

When you execute obj.globalProject.a = "HELLO WORLD", you simply see "OVERRIDE" in the console because you are getting the value of obj.globalProject and setting the value of its data member a.

You do not see "EDITING A DEEP VALUE" in the console because you never set globalProject to refer to a different object, you simply changed one of the underlying object's data members. If you executed something like obj.globalProject = null, however, you would see "EDITING A DEEP VALUE" printed to the console, for you would have changed what object obj.globalProject refers to. See this jsfiddle: http://jsfiddle.net/z7paqnza/1/

like image 196
PaulDapolito Avatar answered Mar 21 '23 07:03

PaulDapolito


What @PaulDapolito said is exactly correct. We are not calling the setter of globalObject when deep object is set. I have updated the code to add setters for deep object and now it calls the inner object setters. Here is the jsfiddle: http://jsfiddle.net/sjLLbqLc/4/

For this particular question, we can do the insert operation inside the GlobalProject class setters.

I am late to the party, but I hope this helps someone who lands up here in search of it.

var ClassA = function() {
  this.globalProject = new GlobalProject(); // this sets global object
  // you can initilaize your default values here to the global object. But you need the new GlobalProject() which    will create the object with setters and getters.
};

Object.defineProperty(ClassA.prototype, 'globalProject', {
  get: function() {
    return this._flag;
  },
  set: function(val) {
    console.log("Setting global object");
    this._flag = val;
  },
});

var GlobalProject = function() {
  Object.defineProperty(GlobalProject.prototype, "a", {
    get: function() {
      return this._a;
    },
    set: function(value) {
      console.log("Seting deep object");
      this._a = value;
    }
  });
  Object.defineProperty(GlobalProject.prototype, "b", {
    get: function() {
      return this._b;
    },
    set: function(value) {
      this._b = value;
    }
  });
};


var obj = new ClassA();

obj.globalProject.a = "HELLO WORLD";// this sets the inner object
like image 24
Vinay Avatar answered Mar 21 '23 07:03

Vinay