JavaScript Variables
js_variables is an object to declare variables intended to be used inside JavaScript templates. This object can store string, number, and boolean variables as well as dictionaries (or objects) and lists (or arrays). These variables will be available in any partial or in any template.
js_variablesonly allowsstring,numberandbooleanvariables as well asdictionariesandlistscontaining otherdictionariesorlistsor the aforementioned primitives. Trying to send other kinds of variables will end in an error.js_variablesdon't compile any template string. So if you set a variable as a template string, it will be interpreted as a string and a warning will be thrown in the console.
Example
The next example will set "Title 80 dog" as the title of the page:
- YAML
- JSON
js_variables:
my_string: 'Title'
my_number: 100
my_boolean: true
my_object:
prop1: 4
prop2: 5
my_array:
- 'cat'
- 'dog'
- 'bird'
title: |
[[[
if (my_boolean) {
return `${my_string} ${(my_number * my_object.prop1) / my_object.prop2} ${my_array[1]}`;
}
return 'Home Assistant';
]]]
{
"js_variables": {
"my_string": "Title",
"my_number": 100,
"my_boolean": true,
"my_object": {
"prop1": 4,
"prop2": 5
},
"my_array": [
"cat",
"dog",
"bird"
]
},
"title": "return (my_boolean) ? `${my_string} ${(my_number * my_object.prop1) / my_object.prop2} ${my_array[1]}` : 'Home Assistant';"
}
Reactive JavaScript Variables (Refs)
The variables placed inside js_variables are static because their value never change. On the other hand, variables placed inside js_refs (called refs) can change their value and they are also reactive. Refs will make your templates be reactive to changes locally, this means that the template will be re-rendered only in the device in which the refs were modified. As regular JavaScript variables, refs will be also available in any partial or in any template.
js_refsonly allowsstring,numberandbooleanvariables as well asdictionariesandlistscontaining otherdictionariesorlistsor the aforementioned primitives. Trying to send other kinds of variables will end in an error.js_refsdon't compile any template string. So if you set a variable as a template string, it will be interpreted as a string and a warning will be thrown in the console.
To access a reactive variable you can use the refs object. Let's see how reactive variables work modifying the previous example to use them:
- YAML
- JSON
js_refs:
my_string: 'Title'
my_number: 100
my_boolean: true
my_object:
prop1: 4
prop2: 5
my_array:
- 'cat'
- 'dog'
- 'bird'
title: |
[[[
if (refs.my_boolean) {
return `${refs.my_string} ${(refs.my_number * refs.my_object.prop1) / refs.my_object.prop2} ${refs.my_array[1]}`;
}
return 'Home Assistant';
]]]
{
"js_refs": {
"my_string": "Title",
"my_number": 100,
"my_boolean": true,
"my_object": {
"prop1": 4,
"prop2": 5
},
"my_array": ["cat", "dog", "bird"]
},
"title": "[[[ return refs.my_boolean ? `${refs.my_string} ${(refs.my_number * refs.my_object.prop1) / refs.my_object.prop2} ${refs.my_array[1]}` : 'Home Assistant' ]]]"
}
Until this point, there are no difference with the regular static variables. But the difference is that if we modify the value of these variables, the title template will be reevaluated using the new values. For example, let's modify the value of some of these variables when an item in the sidebar is clicked and let's check what will be the value of the title on each click.
- YAML
- JSON
js_refs:
my_string: 'Title'
my_number: 100
my_boolean: true
my_object:
prop1: 4
prop2: 5
my_array:
- 'cat'
- 'dog'
- 'bird'
title: |
[[[
if (refs.my_boolean) {
return `${refs.my_string} ${(refs.my_number * refs.my_object.prop1) / refs.my_object.prop2} ${refs.my_array[1]}`;
}
return 'Home Assistant';
]]]
order:
- new_item: true
item: 'Example'
icon: 'mdi:gesture-tap'
on_click:
action: 'javascript'
code: |
refs.my_number *= 2;
refs.my_object = {
...refs.my_object,
prop1: my_object.prop1 + 2
};
{
"js_refs": {
"my_string": "Title",
"my_number": 100,
"my_boolean": true,
"my_object": {
"prop1": 4,
"prop2": 5
},
"my_array": ["cat", "dog", "bird"]
},
"title": "[[[ return refs.my_boolean ? `${refs.my_string} ${(refs.my_number * refs.my_object.prop1) / refs.my_object.prop2} ${refs.my_array[1]}` : 'Home Assistant' ]]]",
"order": [
{
"new_item": true,
"item": "Example",
"icon": "mdi:gesture-tap",
"on_click": {
"action": "javascript",
"code": "refs.my_number *= 2; refs.my_object = { ...refs.my_object, prop1: refs.my_object.prop1 + 2 };"
}
}
]
}
Value of the title after each click:
| Click on the Example item | Title value |
|---|---|
| Initial value | Title 80 dog |
| First click | Title 240 dog |
| Second click | Title 640 dog |
| Third click | Title 1600 dog |
| Fourth click | Title 3840 dog |
| ... | ... |
- To make the templates detect that a reactive variable has been mutated, one needs to assign a new value to the reactive variable. For example, changing the items of an array using
pushorpopwill not make the remplates using that variable to be reevaluated. You need to assign a new array to the value of the reactive variable to make the change be detected. - To make the template aware that it contains a reactive variable, it should be accesed when the template is rendered. If the code accesing the ref variable is not executed when the template renders, then the reactive variable will not be tracked. That is why is recomendable to access reactive variables outside any condition and build the logic using the retrieved value. In this way the template will track that the reactive variable is being used and any time that the variable changes, the template will get re-evaluated.