How to continue if st.stop() is in an if statement?


So I have the following code:

    import streamlit as st

    def calc(name):
        st.write(f'{name}, 1+{len(name)} is {1+len(name)}')
    def name_input():
        txt = st.text_input('Hi, whats your name?')
        if (not txt) & (start==True):
            st.warning('You MUST give me your name')
        st.success(f'Hi {txt}!')

    start = st.button('Let us begin')

    while start == True :

Expectation: no txt input = warning. Txt input = success message

Reality: no txt input = warning. txt input = everything is reset, the textbox closes, no output. Have to click the button to show the textbox again.

I tried if start == True and while start == True but they don’t work. It shows text box, then everything resets after submission.

Wondering if someone has come across a solution? Here’s a repo in case someone would like to reproduce.

Hello @pomkos, welcome to the forum!

First thing to note here, in your if statement, that & is a bitwise AND operator. What you want is a simple and instead: if not txt and start: .... You could even drop that start==True in my opinion.

Now to explain the issue, there are two things to understand with Streamlit:

  1. Everytime you interact with your application (when you click on a button, when you input some text, etc.) the whole script is executed again from the beginning.

  2. When you click a button, it will return True for one run only. Which means when you interact with your text_input, the script reruns, but your button will return False this time, therefore your text input won’t appear.

There are two solutions I would recommend:

  1. Remove that button :sweat_smile:
  2. Use a checkbox instead.

A third solution would be to use session states. But I wouldn’t recommend it because it’s a little bit hack-ish, and in terms of UI experience, I feel like streamlit buttons are meant to execute a one-time operation, and shouldn’t keep a “I was clicked” state. But this is subjective, I give you that solution in case you still want to do it that way :stuck_out_tongue:


Thanks @synode! Great explanation and suggestions. I opted to just remove the button :blush: