Fields that submitted via form are reflected on backend only after the second submit

Summary

Hi, i have a Form for an user to fill his data, the fields values user enter are not updated on first click at submit button. But if user will click submit again (without changing the fields content) the updated data will be reflected at python side.

Steps to reproduce

Code snippet:

import streamlit as st

with st.form(key="create_user"):
    st.text_input(
        label="User Email", key='email'
    )
    st.text_input(
        label="User FullName", key='name'
    )
    st.radio(label='User Role', options=('READER', 'MODERATOR'), horizontal=True, key='role')
    st.form_submit_button(
        label="Confirm creating a user",
        on_click=print,
        args=(st.session_state.name, st.session_state.email, st.session_state.role),
    )

The steps are:

  1. fill name
  2. fill email
  3. select role
  4. click “Confirm creating a user”
    Expected behavior:
    Once button clicked, python side should print entered data
    like this:
    testuser testemail READER

Actual behavior:
First time user click on button, the printed result is:
READER
The second time User click data, the printed results are as expected:
testuser testemal READER

Debug info

  • Streamlit version: 1.16.0
  • Python version: 3.8.10
  • Using Conda? PipEnv? PyEnv? Pex? - nothing like these
  • OS version: Ubuntu 20.04
  • Browser version: FireFox 107

The args argument is evaluated when the submit button is instantiated, not when it is clicked. Thus the callback only sees the old values. The callback can see the current values by using session_state directly.

def on_submit_click():
    print(
        st.session_state.name,
        st.session_state.email,
        st.session_state.role
    )

with st.form(key="create_user"):
    st.text_input(
        label="User Email", key='email'
    )
    st.text_input(
        label="User FullName", key='name'
    )
    st.radio(label='User Role', options=('READER', 'MODERATOR'), horizontal=True, key='role')
    st.form_submit_button(
        label="Confirm creating a user",
        on_click=on_submit_click,
    )