Part of page is getting refreshed on dropdown selection

I am trying to build a simple app where user will enter data & give feedback based on predicted result.

Code:

    import streamlit as st

def main():
	
	st.title("Data Categorization")

	txt = st.text_area("Paste your data here..")

	if st.button("Find Category"):
		try:
			if txt != '':

				value = st.selectbox("Agree with result", ["Yes, I agree..", "Nah!! I don't"])
				
				if st.button("Submit report"):
					if value == "Yes, I agree..":
						#st.write(value)
						print('Do this ...')
					elif value != "Nah!! I don't agree":
						print('Do that ...')

				st.write("Thank You..")
			else:
				st.write('No content found')
		except:
			st.write('Looks like I am having problem connecting my backend')
		
		
if __name__ == '__main__':
	main()

But when I select any value from dropdown:

The rendered elements getting disappears :

Don’t know where I am going wrong. Need help here


1 Like

Hey @deepankar27 welcome to the forums :slight_smile:

What happens here is when you press the second button "Submit report" the script is rerun, and the first button hit "Find category" will go back to None since you hit the second one. So Streamlit won’t go inside the code block from the first button. You need to maintain the info that you pressed the first button somewhere to force Streamlit to go into the code block.

There’s a way to preserve this information inside a state that is preserved between runs, with the State hack. So if you put the State script near your file, you can then do the following :

import streamlit as st
import st_state_patch


def main():
	st.title("Data Categorization")
	txt = st.text_area("Paste your data here..")
	s = st.State() 
	if not s:
		s.pressed_first_button = False

	if st.button("Find Category")  or s.pressed_first_button:
		s.pressed_first_button = True # preserve the info that you hit a button between runs
		try:
			if txt != '':
				value = st.selectbox("Agree with result", ["Yes, I agree..", "Nah!! I don't"])
				if st.button("Submit report"):
					if value == "Yes, I agree..":
						st.write('Do this ...')
					elif value != "Nah!! I don't agree":
						st.write('Do that ...')
			else:
				st.write('No content found')
		except:
			st.write('Looks like I am having problem connecting my backend')
		

if __name__ == '__main__':
	main()
1 Like

Hi @andfanilo Thanks a lot
!! for such a quick response. It worked like a magic spell, I guess I need to get hang of your implementation approach better. Also can you plz help me on how can I set the textarea -> txt blank again after “Submit report” button click & in case I have to reset the state of page to init again?

1 Like

Hey!! I did it using empty() & session run id. Thanks!! But how can I do a reset of all components means the app on each run. Do, I need to change the session key for all components?

import streamlit as st
import st_state_patch
import SessionState


    def main():
    	st.title("Data Categorization")
    	session = SessionState.get(txt = '',run_id=0)
    	controler = st.empty()
    	session.txt = controler.text_area("Paste your data here..")
    	print(controler)
    	print(session.txt)
    	s = st.State() 
    	if not s:
    		s.pressed_first_button = False
    		

    	if st.button("Find Category")  or s.pressed_first_button:
    		session.run_id += 1
    		s.pressed_first_button = True # preserve the info that you hit a button between runs
    		try:
    			if session.txt != '':
    				value = st.selectbox("Agree with result", ["Yes, I agree..", "Nah!! I don't"])
    				if st.button("Submit report"):
    					if value == "Yes, I agree..":
    						st.write('Do this ...')
    						
    					elif value != "Nah!! I don't agree":
    						st.write('Do that ...')
    						controler.text_area("Paste your data here..", key=session.run_id)
    			else:
    				st.write('No content found')
    			
    		except Exception as ex:
    			st.write('Looks like I am having problem connecting my backend')
    			print(ex)
    		

    if __name__ == '__main__':
    	main()

Hi Fanilo @andfanilo

Thank you for the reference. I am still unable to make this work, the error I am getting:
AttributeError: module ‘streamlit’ has no attribute ‘State’

I am trying to pip install st_state_patch or SessionState, and I am getting:
pip install st_state_patch
ERROR: Could not find a version that satisfies the requirement st_state_patch (from versions: none)
ERROR: No matching distribution found for st_state_patch
I appreciate the help!

you need to get the st_state_patch.py file and place it next to your app.py file, then do

import st_state_patch
...
s = st.State()
...

Hi @pchalasani

Could you elaborate on " get the st_state_patch.py file and place it next to your app.py file"?

I meant just copy that file and put it in the same dir as your app script, name it st_state_patch.py

2 Likes

Oh yes, yes! It is working now! Thanks a billion!

2 Likes

Hi I can’t seem to access the state_patch link, has it been removed or incorporated in an update of streamlit package?

never mind, found it!
For anyone else looking:

5 Likes

Hello,
If use the above mentioned solution, it is giving me an attribute error. (module ‘streamlit’ has no attribute ‘State’). Can you please help me?

@Harsh01 there is now a Streamlit native session state you can use for this problem: Session State - Streamlit Docs .

you should be able to replace every st.State by st.session_state.

Have a nice day,
Fanilo :balloon:

I am getting an error with session_state. The error: st.session_state has no attribute “pressed_first_button”. Can someone help me?