Home > front end >  How to access object properties before inizialization in JavaScript/ Typescript?
How to access object properties before inizialization in JavaScript/ Typescript?

Time:02-27

I need to create a "Themes" object, which should contain all the themes with the colors I need for an app. I would like to use some of its variables to change its others. For example, having the "disabled" property set to the text color of the object some opacity. I tried to achieve this by using this.variableName in template literals strings but I get an error saying I can't access it before initialization. Is there any way to achieve this without having to copy-paste the text each time manually?

Code sample:

const Themes = {
    Dark: {
        isDark: true,
        BackgroundColors: {
          primary: '#622BFF',
          page: '#080246',
          floating: '#1C1A70',
          error: '#FF004F',
          warning: '#FCE35E',
          success: '#2ACF58',
          /*I thought adding ${this.variableName} would have worked 
            but unfortunately it didn't
          */
          menu: `
                  linear-gradient(
                    180deg,
                    ${this.Dark.BackgroundColors.floating} 0%, 
                    rgba(242, 24, 155, 0.9) 12%,  
                    ${this.Dark.BackgroundColors.floating} 100%
                  )
                `,
          
        },
        ContentColors: {
          shared: '#622BFF',
          text: '#FFFFFF',
          //adding 99 for opacity
          disabled: `${this.Dark.ContentColors.text}99`,
          inverted: `${this.Dark.BackgroundColors.page}`,
        },
      },
      Light:{
          ......
      }
}

CodePudding user response:

You could achieve that by defining the colors outside of the theme object.

const darkFloating = '#1C1A70'

const Themes = {
  Dark: {
    isDark: true,
    BackgroundColors: {
      floating: darkFloating,
      menu: `
              linear-gradient(
                180deg,
                ${darkFloating} 0%, 
                rgba(242, 24, 155, 0.9) 12%,  
                ${darkFloating} 100%
              )
            `
        }
    }
}

CodePudding user response:

In case the "formulas" are the same for every theme, I'd suggest you use a creator function, i.e.

interface ThemeInput {
  isDark: boolean
  backgroundColors: {
    primary: string
    page: string
    floating: string
    error: string
    warning: string
    success: string
  }
  contentColors: {
    shared: string
    text: string
  }
}

interface Theme extends ThemeInput {
  backgroundColors: ThemeInput['backgroundColors'] & {
    menu: string
  }
  contentColors: ThemeInput['contentColors'] & {
    disabled: string
    inverted: string
  }
}

const createTheme = (input: ThemeInput): Theme => ({
  ...input,
  backgroundColors: {
    ...input.backgroundColors,
    menu: `
      linear-gradient(
        180deg,
        ${input.backgroundColors.floating} 0%,
        rgba(242, 24, 155, 0.9) 12%,
        ${input.backgroundColors.floating} 100%
      )
    `
  },
  contentColors: {
    ...input.contentColors,
    //adding 99 for opacity
    disabled: `${input.contentColors.text}99`,
    inverted: input.backgroundColors.page
  },
})

const Themes = {
  Dark: createTheme({
    isDark: true,
    backgroundColors: {
      primary: '#622BFF',
      page: '#080246',
      floating: '#1C1A70',
      error: '#FF004F',
      warning: '#FCE35E',
      success: '#2ACF58'

    },
    contentColors: {
      shared: '#622BFF',
      text: '#FFFFFF'
    }
  }),
  Light: createTheme({ ... })
}
  • Related