button-card
button-card copied to clipboard
"variables" undefined in nested configuration templates
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
You can't reference variables inside other variables. That's intended because too complex to handle.
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
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.
@amitkeret Did you ever find a workaround for this as this won't get fixed?
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 🙈 🙉 🙊
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.
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 😨