Force st.expander label to update after change

See screenshots towards the end of this post for before (none) and after (6)

I have a sidebar with expanders that represent categories. Clicking each “label” expands down and shows the items below it. I need to show the “number” of selected stories in the label.

I instantiate the st.expander like this:

expander_selected_stories = st.expander(
                label=f"({st.session_state.selected_story_count}) Selected Stories")

Once that is done, I then call a function that loads the stories, generates the button under the expander (with) and this all works great. I verified that the count is returning, but the expander’s use of the session state variable isn’t updating until a page refresh.

Adding st.rerun() at various levels is causing a cascading rerun to happen and I have to exist the terminal app (ctrl+c)

with expander_selected_stories:
                st.session_state.selected_story_count = self.load_selected_stories()

if I do an st.write immediately after this line, it reflects the number

write = st.write(st.session_state.selected_story_count)

So basically… label uses a session state variable in it, some stuff happens, and that label should update and reflect the new value… in this case the number of stories under that ‘category’

Before: (There are already 6 stories under the this ‘label’ by this point - initialized
story-count-a1

After Page Refresh:
story-count-1


I need to be able to draw the component and have this number update. Also another feature is that people can change what a stories’ category is making it to where these counts could change quite a bit dynamically.

HI @StreamlitCowboyCoder ,

This can be done by keeping an inventory list of what is clicked in session state and the updates made via callback to avoid forced reruns. Here is a sample code:

import streamlit as st

if "selected_list" not in st.session_state:
    st.session_state["selected_list"] = []


def story_selection(key_element):
    if st.session_state[key_element] == True:
        st.session_state["selected_list"].append(key_element)
    else:
        st.session_state["selected_list"].remove(key_element)


with st.sidebar:
    with st.expander(
        f'({len(st.session_state["selected_list"])}) Selected Stories', expanded=True
    ):
        for i in range(10):
            st.checkbox(
                f"Story {i+1}",
                on_change=story_selection,
                args=[f"story_{i}"],
                key=f"story_{i}",
            )

Screen-Recording-2023-10-19-at-8
Hope it helps!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.