Reputation: 18592
I want to define getter method on object so that when I access a property , getter method fires
object.someProperty // this fires object.get(name) where name is someProperty
this is an example illustrate my thought
file : data.js
import setting from 'setting';
const data = {
a : {
foo : 1 ,
bar : 2
} ,
b : {
foo : 3 ,
bar : 4
}
}
//DEFINE GETTER
//something like this
data.DEFINE_GETTER(function(property)
{
if(setting.type === 'a')
return data['a'][property];
else
return data['b'][property];
})
export default data;
file : test.js
import data from 'data';
import setting from 'setting';
setting.type = 'a';
console.log(data.foo) //should be 1
console.log(data.bar) //should be 2
setting.type = 'b';
console.log(data.foo) //should be 3
console.log(data.bar) //should be 4
Upvotes: 0
Views: 88
Reputation: 109
I made a plunker that may help https://plnkr.co/edit/eRsgBXQackUgZkg84lZj?p=info
First of all if you want to access any property from an object that must be in that object.
So, data.foo will be usable only when you create an object/function of foo inside data.
Now we need a dynamic pointing object that point to Data.Child.Childobjects
So, I created a function AddProperty just pass the name of ParentObject and childchildobject. Write your logic inside it.
var setting = {type : null};
var data = {
a : {
foo : 1 ,
bar : 2
} ,
b : {
foo : 3 ,
bar : 4
}
}
function AddProperty(baseObject = null, ChildChildProperty = null)
{
if(baseObject != null && ChildChildProperty != null)
{
Object.defineProperty(baseObject, ChildChildProperty, {
get: function() {
if(setting.type === 'a')
return data['a'][ChildChildProperty];
else
return data['b'][ChildChildProperty];
},
set: function(name) {
if(setting.type === 'a')
data['a'][ChildChildProperty] = name;
else
data['b'][ChildChildProperty] = name;
}
});
}
}
AddProperty(data,'foo');
AddProperty(data,'bar');
setting.type = 'a';
console.log(data.foo) //should be 1
console.log(data.bar) //should be 2
setting.type = 'b';
console.log(data.foo) //should be 3
console.log(data.bar) //should be 4
Upvotes: 0
Reputation: 68393
You can define a getter
Object.defineProperty(data, 'foo', {
get: function() { return this[setting.type].foo }
});
Object.defineProperty(data, 'bar', {
get: function() { return this[setting.type].bar }
});
Edit
You can refactor the defineProperty
to a method that iterate all the different keys in the data
function defineDataProp( obj, setting )
{
Object.keys(Object.values( obj )[0]).forEach( function(key){
Object.defineProperty(obj, key, {
get: function() { return this[setting.type][ key ] }
});
})
}
Demo
const data = {
a : { foo : 1 , bar : 2 } ,
b : { foo : 3 , bar : 4 }
};
var setting = { "type" : "a" };
defineDataProp( data, setting );
setting.type = 'a';
console.log(data.foo,data.bar)
setting.type = 'b';
console.log(data.foo,data.bar)
function defineDataProp( obj, setting )
{
Object.keys(Object.values( obj )[0]).forEach( function(key){
Object.defineProperty(obj, key, {
get: function() { return this[setting.type][ key ] }
});
})
}
Upvotes: 1
Reputation: 68655
You can look at Proxies.
const data = {
a : {
foo : 1 ,
bar : 2
} ,
b : {
foo : 3 ,
bar : 4
}
}
const setting = {
type: 'a'
};
const products = new Proxy({
data: data
},
{
get: function(obj, prop) {
return obj.data[setting.type][prop];
},
set: function(obj, prop, value) {
obj.data[setting.type][prop] = value;
}
});
console.log('Before type change');
console.log(products.foo);
setting.type = 'b';
console.log('After type change');
console.log(products.foo);
products.foo = 4;
console.log('After value change');
console.log(products.foo);
setting.type = 'a';
console.log('After type change');
console.log(products.foo);
Upvotes: 3
Reputation: 7288
Use proxy handler
let handler = {
get(target, propKey, receiver) {
console.log('get ' + propKey);
if(setting.type === 'a')
return data['a'][propKey];
else
return data['b'][propKey];
}
};
let proxyData = new Proxy(data, handler);
// now you can call
proxyData.foo
proxyData.bar
Upvotes: 1