user1595858
user1595858

Reputation: 3890

execute function when setting an object

I want to execute a function when the value of props.test is changed. I have seen in another question Object.defineProperty can be used. But in my case it will props.test, how to make it work

 props.test = props.test || {};
//if props.test value changes it need to execute set function
props.test = "abc";

function setTest(){
console.log("set function is executed");
props.test = "abc";
}

Upvotes: 1

Views: 91

Answers (2)

Anthony Forloney
Anthony Forloney

Reputation: 91806

This could be achieved by defining getter and setters on an object such as,

var props = { 
    get value() { 
       return this._value; 
    }, 
    set value(val) { 
        this._value = val;
        alert("value is: " + val); 
    }
}

For the above example, when you set the value on the props object, an alert function is executed,

props.value;           // returns undefined
props.value = "hello"; // alert box will appear, "value is: hello"
props.value;           // returns "hello".

This can be replaced with the function you wish to execute when the value changes.

When adding properties onto an existing object you can use Object.defineProperty like so,

var me = {name:'Anthony', location:'RI'};
// let's extend onto the object a new property called, 'age'
// with custom getter and setter
Object.defineProperty(me, 'age', { 
        get: function() { 
                return this._age; 
        }, 
        set: function(newAge) { 
                this._age = newAge;
                alert("I am " + newAge + " now!"); 
        }
});

me.age;        // undefined
me.age = 28;   // alert box will appear, "I am 28 now!"
me.age;        // returns 28.

To take it one-step further if the pre-existing object contains an object, you can perform the following,

Note: Object.defineProperty takes as arguments an, object, key, and descriptor (ie, our custom setters and getters) respectively. That object argument can be any object type, even the nested object of the parent object.

// my pet rules my life, so let's include her in my example object,
var me = {name:'Anthony', location:'RI', pet:{name:'Binks'}};
// let's give her an identifier because that's what good owners do,
// Notice the first argument of, 'me.pet' which is the inner object.
Object.defineProperty(me.pet, 'id', {
        get: function() { 
                return this._id; 
        }, 
        set: function(newId) { 
                this._id = newId; 
                alert("id changed! " + newId); 
        }
});

me.pet['id'];     // undefined
me.pet['id'] = 1; // alert box will appear, "id changed! 1"
me.pet['id'];     // returns 1

Update: 07/12/2015

If you are trying to add dynamic values onto an Object, you can extend the above functionality into a generalized function,

var defineProp = function(obj, value) {
    Object.defineProperty(obj, value, {
        get: function() { 
                return this['_' + value]; 
        }, 
        set: function(newValue) { 
                this['_' + value] = newValue; 
                alert(value + " changed! " + newValue); 
        }
    });
}

Upvotes: 4

Jon Trauntvein
Jon Trauntvein

Reputation: 4554

The most logical way of doing this is to create a function that is responsible for setting the property. To the best of my knowledge, there is no hook available to monitor when the property of an object has been changed. Alternatively, you object could use a timer to periodically check to see if the property has changed.

Upvotes: 0

Related Questions