Home > other >  How to return a default value in a object's attribute
How to return a default value in a object's attribute

Time:11-03

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.

  1. If I do console.log(primary.green) this should return a default hex string: #def and not the object { dark: ..., light: ... }

  2. 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}`);

  • Related