I have to select twice when using selectbox

Running locally
Python 3.11.6
Streamlit 1.28.0

The functions of my code are:

  1. can add cell or delete cell by click +/- button
  2. can select items by selectbox

However, I have to select twice when I use selectbox.
The first time I select, the item will return to previous value.
(e.g. I select β€œA”, then I want to change to β€œB” so I select β€œB”, but the value will be β€œA”. )
And the second time I select it, it will be fine.

I have tried Session_state stored selectbox needs to be clicked twice, the similar situation of mine, but it not work for me.
(More precisely, when I add for k, v in st.session_state.items(): st.session_state[k] = v, I will get " StreamlitAPIException : Values for st.button, st.download_button, st.file_uploader, st.data_editor, st.chat_input, and st.form cannot be set using st.session_state.". I tried to try-except to exclude the issue, but I’m not sure whether it will be some mistakes or not.)

My code is this

import streamlit as st
import uuid

# initialize
if 'var' not in st.session_state:
    st.session_state.var = [None]
if 'uuid' not in st.session_state:
    st.session_state.uuid = [None]
selectbox_list = ['A','B','C']

# add new cell
def add_cell(index):
    element_id = str(uuid.uuid4())
    st.session_state.uuid.insert(index, element_id)
    st.session_state.var.insert(index, None)

# delete the cell
def delete_cell(index):
    if len(st.session_state.uuid) > 1:
        del st.session_state.uuid[index]
        del st.session_state.var[index]

# generate cell by feature saved at st.session_state
def gen_cell(index):
    element_id = st.session_state.uuid[index]
    cols = st.columns(2)
    
    # selectbox
    with cols[0]:
        if st.session_state.var[index] is None:
            selectbox_value = st.selectbox(f'Cell {index}', selectbox_list, index=None,key=f'selectbox_{element_id}')
        else:
            selectbox_value = st.selectbox(f'Cell {index}', selectbox_list, index=selectbox_list.index(st.session_state.var[index]),key=f'selectbox_{element_id}')
    # button
    with cols[1]:
        cols2 = st.columns(3)
        with cols2[1]:
            st.write('')
            st.write('')
            st.button('\+',key=f"add_{element_id}",  on_click=add_cell, args=[index+1])
        with cols2[2]:
            st.write('')
            st.write('')
            st.button("\-", key=f"delete_{element_id}", on_click=delete_cell, args=[index])
    
    return {'var': selectbox_value}

# feature save
rows_collection = []
for index in range(len(st.session_state.var)):
    row_data = gen_cell(index)
    rows_collection.append(row_data)

# asign feature
if len(rows_collection) > 0:
    for i in range(len(rows_collection)):
        st.session_state.var[i] = rows_collection[i]['var']

Thank you.

Hey Gavin,
I hope I’m not too late. Try to manually set every key to itself. Sounds weird, but works. it is the same idea as the one you got but session_state has a variable to much stored, which you didnt insert there.
So for every widget key do:
st.session_state.widget_key = st.session_state.widget_key

Hpoe this helps!

1 Like