Form Submit Button is saving widget inputs late/lagging

Hi, I am having issues with saving a dictionaries into a session state list via a form and submit button.

Code to reproduce:

import streamlit as st
from streamlit_tags import st_tags

st.write('# GROUP EXPENSE SPLITTING')

people_list = st_tags(
    label='# Enter Names:',
    text='Press enter to add more',
    value=['person1','person2','person3']
)

if 'split_list' not in st.session_state:
    st.session_state['split_list'] = [   ]  #this is an empty list

def add_payer(split_list,payer,expense,cost):
    payer_dict = dict(Payer = payer, Expense = expense, Cost = cost)
    split_list.append(payer_dict)

with st.form('my_form', True):
    st.write(' ## Input expense information:')
    payer = st.selectbox('Who paid?',options=people_list)
    expense = st.text_input('What did they pay for?')
    cost = st.number_input('How much was it?')
    owers = st.multiselect('Who is a part of this expense?',options=people_list,default=people_list)
    
    st.form_submit_button('Add expense',
                          on_click=add_payer,
                          args=(st.session_state['split_list'],payer,expense,cost))

st.session_state

When running this code, I change some of the inputs within the form. Eg. “person2, food, 100” and then I press the button to submit (first button click).
At the bottom of the page where st.session_state is shown, it refreshes to show the original default values on the form as appended to the list. (ie. "person1, " “, 0.0”)
And then I change the form inputs and submit a new set of inputs (second button click), but when the st.session_state refreshes, it shows the previous inputs from my first button click.
It’s as if the appending to st.session_state[‘split_list’] is one step behind the button click?

(Edited post to use preformatted text rather than quotes)
image

You’ll want to use session state inside of the add_payer method to get the entries from the form, because inside of a form, variables returned from a form don’t work the same way as they do outside the form, so the updated values won’t be automatically passed to the add_payer method even though you specify them in args

import streamlit as st
from streamlit_tags import st_tags

st.write("# GROUP EXPENSE SPLITTING")

people_list = st_tags(
    label="# Enter Names:",
    text="Press enter to add more",
    value=["person1", "person2", "person3"],
)

if "split_list" not in st.session_state:
    st.session_state["split_list"] = []  # this is an empty list


def add_payer():
    split_list = st.session_state["split_list"]
    payer = st.session_state["payer"]
    expense = st.session_state["expense"]
    cost = st.session_state["cost"]
    payer_dict = dict(Payer=payer, Expense=expense, Cost=cost)
    split_list.append(payer_dict)


with st.form("my_form", True):
    st.write(" ## Input expense information:")
    payer = st.selectbox("Who paid?", options=people_list, key="payer")
    expense = st.text_input("What did they pay for?", key="expense")
    cost = st.number_input("How much was it?", key="cost")
    owers = st.multiselect(
        "Who is a part of this expense?",
        options=people_list,
        default=people_list,
        key="owers",
    )

    st.form_submit_button(
        "Add expense",
        on_click=add_payer,
    )

st.session_state

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