button-card icon indicating copy to clipboard operation
button-card copied to clipboard

"variables" undefined in nested configuration templates

Open amitkeret opened this issue 2 years ago • 7 comments

Checklist

  • [x ] I updated the card to the latest version available
  • [ x] I cleared the cache of my browser

Describe the bug I've declared a configuration template that is nested within another configuration template. The nested template cannot take variables sent to it (from local config), and pass them through to the parent template.

Version of the card Version: 3.4.2

To Reproduce This is the configuration I used:

button_card_templates:

  button_info:
    variables:
      info_icon: information
    show_label: true
    label: '[[[ return variables.info ]]]'
    icon: '[[[ return "mdi:" + variables.info_icon ]]]'

  sensor_battery_info:
    template: button_info
    variables:
      info: '[[[ return states[variables.info_entity].state + "%" ]]]'
      info_icon: battery

# This works fine
type: custom:button-card
  template: button_info
  entity: media_player.player1
  variables:
    info: 'Player1 active'

# This throws the error below
type: custom:button-card
  template: sensor_battery_info
  entity: binary_sensor.contact_sensor_01
  variables:
    info_entity: sensor.contact_sensor_01_power

Error message On Firefox: ButtonCardJSTemplateError: TypeError: variables is undefined in 'return states[variables.info_entity].state + "%"' On Edge: ButtonCardJSTemplateError: TypeError: Cannot read property 'info_entity' of undefined in 'return states[variables.info_entity].state + "%"'

Expected behavior The variables object should be available to the nested template at the time of defining its own variables, to allow passing variables: Local config > nested template > parent template. I cannot think of a workaround to this issue, unfortunately. I don't think a second (non-nested) template would solve this.

Desktop (please complete the following information):

  • Browser: tested on Firefox and Edge.
  • Version Firefox 91.0.1, Edge 92.0.902.78

Smartphone (please complete the following information):

  • Android 11 on Pixel 5, HASS Companion App

amitkeret avatar Aug 22 '21 06:08 amitkeret

You can't reference variables inside other variables. That's intended because too complex to handle.

RomRider avatar Aug 22 '21 06:08 RomRider

OK... This seems like a pretty common use case to me - creating a "base" template and re-using it as a foundation for other (nested) templates. And from the nested templates, wanting to pass-through variables back to the base template. Can you suggest a workaround for this use-case then? I can't think of any.

I can easily think of another hypothetical example. Just illustrating how common this use-case can get.

base template:
  tap_action: call-service
  service: input_boolean.turn_on
  target:
    entity: '[[[ return variables.entity ]]]'
  icon: '[[[ return `mdi:${variables.icon}` ]]]'

ring_template:
  template: base_template
  variables:
    icon: bell-ring
    entity: '[[[ return variables.entity ]]]'

- type: custom:button-card
  template: base_template
  variables:
    icon: eye
    entity: input_boolean.toggle1
- type: custom:button-card
  template: ring_template
  variables:
    entity: input_boolean.toggle2

amitkeret avatar Aug 22 '21 11:08 amitkeret

All the variables are evaluated in one shot whenever the card needs an update that's why there's no dependency possible between them. Once the config is loaded, there's no config templates anymore, it's as if you had a flat config with everything for your card (this happens once, when the card loads).

Your request is easy to understand from a logical point of view but complex to implement from a code perspective.

RomRider avatar Aug 22 '21 18:08 RomRider

@amitkeret Did you ever find a workaround for this as this won't get fixed?

Vedeneb avatar Dec 21 '21 16:12 Vedeneb

Unfortunately, the best I found was to take the desired variables out of the variables section... let me explain. Since button-card supports overriding configurations, you can, instead of passing variables to nested templates, overwite the base template's config.

So, if I wanted to have an info variable to be usable in a nested template:

button_card_templates:

  button_info:
    variables:
      info: "Some info"
      info_icon: information
    show_label: true
    label: '[[[ return variables.info ]]]'
    icon: '[[[ return "mdi:" + variables.info_icon ]]]'

  sensor_battery_info:
    template: button_info
    variables:
      # Pass a dummy variable to avoid error
      info: " "
      info_icon: battery
    # The following line overwrites the above template's config for "label"
    label: '[[[ return entity.state + "%" ]]]'

It's hacky, but it works 🙈 🙉 🙊

amitkeret avatar Dec 26 '21 23:12 amitkeret

Unfortunately, the best I found was to take the desired variables out of the variables section... let me explain. Since button-card supports overriding configurations, you can, instead of passing variables to nested templates, overwite the base template's config.

So, if I wanted to have an info variable to be usable in a nested template:

button_card_templates:

  button_info:
    variables:
      info: "Some info"
      info_icon: information
    show_label: true
    label: '[[[ return variables.info ]]]'
    icon: '[[[ return "mdi:" + variables.info_icon ]]]'

  sensor_battery_info:
    template: button_info
    variables:
      # Pass a dummy variable to avoid error
      info: " "
      info_icon: battery
    # The following line overwrites the above template's config for "label"
    label: '[[[ return states[variables.info_entity].state + "%" ]]]'

It's hacky, but it works 🙈 🙉 🙊

Hi there @amitkeret could you explain your example? ive hit this problem too and im pulling my hair out.. What i dont understand is where the variable 'info_entity' comes from? I see the variable info and info_icon.. I see that you are overriding the label in the nested template.. where is info_entity defined? Thanks.

u8915055 avatar Apr 03 '22 20:04 u8915055

where the variable 'info_entity' comes from?

Oooooops that's a typo... should be the state of entity as expected. I've amended my comment above. I'm sorry @u8915055 for all the hairs you pulled 😨

amitkeret avatar Apr 19 '22 07:04 amitkeret