It is a bit too hard to find a fitting title for the problem. So if you have an object:
const primary = {
green: {
dark: '#dark' <-- hex code
light: '#light'
...: '#...'
}
}
I would like the following functionality.
If I do
console.log(primary.green)
this should return a default hex string:#def
and not the object{ dark: ..., light: ... }
If I do
console.log(primary.green.dark)
this should return the hex string#dark
A clear option would be to add default
attribute inside the primary.green
object. So it would be primary.green.default
. However I would like to avoid this.
I have tried to do thinks with getter, but was unsuccessful.
CodePudding user response:
One solution can be to use a proxy getter to return a function that takes the non-default option as an argument. Not exactly the behaviour you want, but similar.
const primary = {
green: {
dark: '#dark',
light: '#light'
}
}
const handler = {
get: (obj, prop, receiver) => {
return (key) => obj[prop][key] || obj[prop].dark
}
}
const proxyPrimary = new Proxy(primary, handler)
console.log(proxyPrimary.green())
console.log(proxyPrimary.green('light'))
CodePudding user response:
You can't per se.
JavaScript has no way of giving you a value for x
but a different value for x
if you then go on to access a property of it.
What you can do is add a toString
method to the object so if it is used in a context that casts it to a string, you get the value you want instead of "[object Object]"
.
const primary = {
green: {
dark: '#dark',
light: '#light',
toString: function () { return this.dark; }
}
}
console.log(primary.green.dark);
console.log(primary.green);
console.log(`${primary.green}`);
This is obviously quite a lot of work to do by hand so you'll probably want to build a function to transform the code you wrote into code where every object has a suitable toString
method on it.
const ThemeColor = {
toString: function () { return this.dark; }
};
const myThemeData = {
green: {
dark: '#dark',
light: '#light',
},
red: {
dark: '#dark',
light: '#light',
},
};
const themeBuilder = (themeData) => Object.fromEntries(
Object.entries(themeData).map(
([colorName, versions]) => [colorName, {...ThemeColor, ...versions}]
)
);
const primary = themeBuilder(myThemeData);
console.log(`${primary.green}`);
console.log(`${primary.red} / ${primary.red.dark} / ${primary.red.light}`);