Click twice on button for changing state

Summary

Hi there, In my application, I have two buttons: “Create” and “Edit.” These buttons are supposed to take the user to the next page by changing the session state but I need to click twice in order an action to accrue.

Steps to reproduce

Code snippet:

def main():
    # Initialize session_state if it doesn't exist
    if "page" not in st.session_state:
        st.session_state.page = ""
        st.session_state.selected = None  # Add a session state for selected

    if st.session_state.page == "edit":
        table_name = st.session_state.selected  # Use the saved selected value
        edit_table = EditTable(table_name)
        edit_table.show_ui()
        if st.button('Back'):
            st.session_state.page = ""

    elif st.session_state.page == "create":
        st.title("Create New Table")
        FactTable()
        if st.button('Back'):
            st.session_state.page = ""

    else:
        # default is home page
        home_instance = HomePage()
        home_instance.generate_home_page()

        if st.button('Edit Table'):
            if home_instance.selected:
                st.session_state.page = "edit"
                st.session_state.selected = home_instance.selected[0]['Table Name']  # Save selected value to session_state
            else:
                #call to warning function that prints a warning
                warning("Select a table to edit.")

        if home_instance.created_button:
            st.session_state.page = "create"


if __name__ == '__main__':
    main()

Expected behavior:

I’m facing an issue where I have to click a button twice for the action to be triggered. It’s not necessary to click the same button twice; for example, I could click the “Edit” button once, nothing happens, then I click the “Create” button, and only then do I go to the edit page.

I’ve tried adjusting the order of the code because I know Streamlit reads from top to bottom each time, but the problem persists. Any assistance would be greatly appreciated!

Actual behavior:
After click on “Create” or “Edit” buttons -take the user to the next page by changing the session state (and current page the user click on the buttons from will be invisible)

Debug info

  • Streamlit version: 1.22.0
  • Python version: Python 3.7.13
  • Using Conda? No
  • OS version: mac os 12.6.3
  • Browser version: Version 113.0.5672.126

Requirements file

streamlit
numpy
asyncio
pandas
streamlit-aggrid

1 Like
if st.button('Back'):
    st.session_state.page = ""

When you have a snippet like this.

  1. The user clicks the button
  2. The script reruns
  3. The button is True and the conditional code executes
  4. The script ends

It’s not until the script reruns again that the new value of st.session_state.page will be reflected at the top of the script where you need it to correctly logic gate your code.

Option 1: Add st.experimental_rerun()

You can cause a second rerun to happen by adding st.experimental_rerun() after any line changing the value of st.session_state.page

if st.button('Back'):
    st.session_state.page = ""
    st.experimental_rerun()

Option 2: Use a callback

If you want the button to set the page before the script reruns, you can use a callback.

import streamlit as st

if 'page' not in st.session_state:
    st.session_state.page = 'home'

def set_page(page):
    st.session_state.page = page

st.write(f'The page is {st.session_state.page}')

st.button('Home', on_click=set_page, args=['home'])
st.button('Edit', on_click=set_page, args=['edit'])
st.button('Create', on_click=set_page, args=['create'])


st.write(f'The page is {st.session_state.page}')
1 Like

@mathcatsand
It worked! Thank you so much

Hi @mathcatsand

I have some buttons in the sidebar as below :

with st.sidebar:
anonymize=st.button(“Anonymize”)
summary=st.button(“Summary”)
intent=st.button(“Intent”)
subject=st.button(“Subject”)
sentiment=st.button(“Sentiment”)

But I am facing a issue , I need to click a button twice for first time to perform any action on it .
Can you please help me with this ?

Can you provide a minimal, reproducible code sample? I’m not sure what happens after the buttons to take action. Can you provide a simplified example, maybe with one button, so I have runnable app to look at?

@mathcatsand
When I click on Anonymize button , I need to click it twice to make Download button visible for the first time when UI is loaded but after that Download button is visible after first click .Below is the code:

with st.sidebar:
anonymize=st.button(“Anonymize”)
if anonymize:
st.download_button(
label=“Download Anonymized File”,
data=text,
file_name=“output.txt”,
mime=“txt”,
)

Your code works for me. As soon as I click “Anonymize” (only once), the download button appears.

I’m having the same issue as @preet_chaudhary. It was working before but now it doesn’t work and I need to click button twice for it to get into the condition.

Did you find out what was going on?

Hi, how can you create Edit page in streamlit? Because i looking for, but not find nothing, can you tell me?

I had same issue. This works like charm. Thanks for sharing.