Ali Faris
Ali Faris

Reputation: 18592

define getter method on object - javascript

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

Answers (4)

Harsh Chaurasia
Harsh Chaurasia

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

gurvinder372
gurvinder372

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

Suren Srapyan
Suren Srapyan

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

Naren Sisodiya
Naren Sisodiya

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

Related Questions