The issue was fixed:
I was able to workaround the bug, writing the solution here in case anyone finds it in the future.
The problem was, that if the index=___
parameter is passed to selectbox()
, it is part of the ID. So if the index changes throughout the lifecycle of the app, the widget becomes a different one and the state breaks. The solution was to inject the default value not through the index=___
parameter, but through the session state. Fixed code below:
def selectbox_with_query_storage(label: str, options: List[Any], query_param_name: str, **kwargs):
key = kwargs.pop("key", f"selectbox_with_query_storage_{query_param_name}")
has_value_from_previous_renders = key in st.session_state
current_query_params = st.experimental_get_query_params()
current_value_params = current_query_params.get(query_param_name, [])
query_value = None
if len(current_value_params) == 1:
query_value_str = current_value_params[0]
query_value = type(options[0])(query_value_str) # Deduce type from first option and convert.
# There are two ways to set a preselected value in a selectbox - using the session state and the index=___ param.
# The index=___ method causes problems if the index changes during the run, so we opt for the session state.
# https://discuss.streamlit.io/t/set-selectbox-value/18376/4
if query_value and not has_value_from_previous_renders:
st.session_state[key] = query_value
value = st.selectbox(label, options, key=key, **kwargs)
if value != query_value:
current_query_params[query_param_name] = value
st.experimental_set_query_params(**current_query_params)
return value