Widgets inside of an expander do not show the correct state if all the following are true:
They have been initialised using st.session_state
Code that is run after an if st.checkbox() is run
They have not been opened before 2) occurs
The variable set to the widget is correct but the displayed value is not.
Steps to reproduce
import streamlit as st
defaults = {'foo':5,'bar':10}
for default in defaults:
if default not in st.session_state:
st.session_state[default] = defaults[default]
foo = st.number_input('foo',key='foo')
with st.expander('bar'):
bar = st.number_input('bar',key='bar')
if st.checkbox('foo + bar'):
st.write(foo + bar)
Steps to reproduce:
Run the app
Don’t open the expander
Click the checkbox
Now open the expander
Expected behavior:
The widget inside the expander correctly shows its value: 10
Actual behavior:
The widget inside the expander displays its value as 0, even though the variable it is set to has the correct value (10)
The behavior is also present if you do the following steps:
Run the app
Don’t open the expander
Change the value of the “foo” number_input either using keyboard entry or the +/- buttons
Now open the expander
It does NOT happen if you add st.tabs to the page and replace step 3 with “change from one tab to another”.
It does NOT happen if you replace the expand box with st.tabs and put the “bar” number-input on a second tab.
So it seems the bug requires:
“Fresh” session state (where the “bar” widget has not yet been drawn)
An input element in an expand-box
An update to page state?
I suspect this is a problem with the front-end since on the python side the app is behaving as expected. I am not a JS-familiar person so I can’t help much other than confirm the unexpected behavior.
This also happens for other inputs besides number_input:
Steps to reproduce:
import streamlit as st
defaults = {'foo':5,'bar':"default"}
for default in defaults:
if default not in st.session_state:
st.session_state[default] = defaults[default]
foo = st.number_input('foo',key='foo')
with st.expander('bar'):
bar = st.text_input('bar', key='bar')
if st.checkbox('foo + bar'):
st.write(str(foo) + bar)