Home > Back-end >  Trouble passing the name of a property as a value
Trouble passing the name of a property as a value

Time:10-20

I am trying to set a badge color without having to import the palette with my colors into another file.

I have my routes.js that has the following for a nav item:

{
    name: "Notifications",
    icon: <Icon fontSize="small">email</Icon>,
    notifications: notificationsNumber,
    badgeColor: "ywpYellow.main",
}

Now. ywpYellow is defined in colors.js like so:

const colors = {
    ywpYellow: {
        main: "#FEB913",
        focus: "#FEB913",
    },

Now I want to take badgeColor and have it display ywpYellow.

If I do this, it works, because ywpYellow is defined in palette from an import on colors.js

function SidenavCollapse({ icon, name, notifications, badgeColor, ...rest }) {
   const badgeStyle = ({palette: {ywpRed, ywpWhite, ywpYellow, ywpBlue}}) => ({
      background: ywpYellow.main,  // THIS WORKS BECAUSE IT'S A DEFINED OBJECT
   });

What would be the correct way of this pseudocode

background: badgeColor,

when badgeColor is a string containing the nomenclature of the object (ywpYellow.main) I am trying to call?

I have tried palette[badgeColor]

I have tried setting badgeColor as an object: badgeColor: ['ywpYellow', 'main'], and just calling it background: badgeColor

I have also tried the following (both ways):

const badgeStyle = ({palette: colors}) => ({
   background: colors[badgeColor].main,
   // background: colors[badgeColor],

to no avail.

CodePudding user response:

Change your deconstruction to just:

const badgeStyle = ({palette}) => {...}

Which should be equivalent to:

const palette = {
    ywpYellow: {
        main: "#FEB913",
        focus: "#FEB913",
    }
}

If the property was just one level deep the syntax would be like this:

const badgeColor = 'main';
const backgroundColor = palette.ywpYellow[badgeColor];

Because the path is nested it's a bit more complicated. You should use an array of property names, or just two separate ones.

const badgeColor = ['ywpYellow', 'main'];
const backgroundColor = palette[badgeColor[0]][badgeColor[1]];

If there is a variable amount of property names you can iterate through them.

const badgeColor = ['ywpYellow', 'main'];
let backgroundColor = palette;
for (const propName of badgeColor) {
  backgroundColor = backgroundColor[propName];
}

If you want to pass in the dot notation, then you can just split the string on the dot.

const badgeColor = 'ywpYellow.main';
const propNames = badgeColor.split('.');
let backgroundColor = palette;
for (const propName of propNames) {
  backgroundColor = backgroundColor[propName];
}

Example: https://stackblitz.com/edit/typescript-rdbmmu?file=index.ts


Here's what your final result could look like:

function SidenavCollapse({ icon, name, notifications, badgeColor, ...rest }) {
  const badgeStyle = ({ palette }) => {
    const propNames = badgeColor.split('.');
    let backgroundColor = palette;
    for (const propName of propNames) {
      backgroundColor = backgroundColor[propName];
    }
    return { background: backgroundColor };
  };
}
  • Related