Multiselect needs double click to clear (query params)

I am experiencing extremely odd behavior with st.query_params and multiselect.

A user can be redirected to the page with an option already set for the multiselect. However, I also want the app the actively set the query params, such that it is easy for users to share the page with one another.

However, when “deselecting”/clearing the multiselect it needs to be clicked twice in order for Streamlit to clear the query params and to clear the selection in the multiselect. I am running the app locally. Below is a reproducible example, currently running with the latest Streamlit version == 1.38.0:

import streamlit as st

st.set_page_config(page_title="Test")

query_params = st.query_params.to_dict()

options = ["Option 1", "Option 2", "Option 3"]

selected_option = st.multiselect(
    label="Select Option",
    options=options,
    default=query_params.get("option", []),
    max_selections=1,
)

if selected_option:
    st.success("Success")
    st.query_params.option = selected_option

else:
    st.query_params.clear()
    st.stop()

Any help is really appreciated - thanks!

Hello,
Why are you not using the selectbox/ session_state ?

        options = ["Option 1", "Option 2", "Option 3"]

        selected_option = st.selectbox(
            label="Select Option",
            options=options,
            index=options.index(st.session_state.get('option', options[0])))

        if selected_option:
            st.success("Success")
            st.session_state['option'] = selected_option
        else:
            st.stop()

I managed to fix it such that the query params are set both when selecting and deselecting an option. It is also passed to session state to control the “flow” of the report. See the code below:

import streamlit as st
 
def set_query_param(
        url_key: str,
        session_state_key: str,
):
    if st.session_state[session_state_key]:
        st.query_params[url_key] = st.session_state[session_state_key]
    else:
        st.query_params.clear()
        del st.session_state[session_state_key]
 
st.set_page_config(page_title="Test")
 
query_params = st.query_params.to_dict()
 
options = ["Option_1", "Option_2", "Option_3"]
 
selected_option = st.multiselect(
    label="Select Option",
    options=options,
    default=query_params.get("option", []),
    max_selections=1,
    key="selected_option",
    on_change=set_query_param,
    args=["option", "selected_option"],
)
 
st.write(f"session state: {st.session_state.selected_option}")
 
st.write(f"multiselect state: {selected_option}")
 
if any(st.session_state.selected_option):
    st.session_state.run_report = True
else:
    st.session_state.run_report = False
   
if not st.session_state.run_report:
    st.warning("Please select an option")
    st.stop()
 
st.success("Success")