Get values immedetaily after callback/on_change

I’m confused how to immediately get the most recent values of the multiselect after a callback (using on_change).

Using the below script, if I remove any of the items from the multiselect through the interface, the values being printed through the callback are showing the old values (before removal).
It’s constantly lagging by one item. It does show the right values if I write them out after it passes the part in the script again where the multiselect is declared. However, it is mandatory to declare the callback (on_change) function BEFORE.

import streamlit as st


def main():
    items= [1,2,3,4]

    def get_new_values_list():
        st.write(values) # < returns list before removal

    values = st.multiselect('issue', items, items, on_change=get_new_values_list)

    st.write(values) # < returns correct list


if __name__ == '__main__':
    main()

Try this:

import streamlit as st

def main():
    items = [1,2,3,4]
    def get_new_values_list():
        st.write(st.session_state['issue'])
    values = st.multiselect('issue', items, items, on_change=get_new_values_list, key='issue')
    st.write(values) # < returns correct list

if __name__ == '__main__':
    main()
2 Likes

Great! That works. So if I understand it well, the key argument gives a user named handle that can be consumed through the session state at any point in time?

1 Like

Well, yes. Though the callback pattern is typically used to set values before the script that comes after the widget is run. It’s useful for instance to set other session state variables to use as the values of widgets that will be displayed based on the value of the widget making the callback. You may have noticed for example that a checkbox’s state doesn’t “stick” through a rerun unless it is clicked twice. If you set its current value session state via its callback, then you can indeed make the state “stick”. E.g. you can also change the contents of other widgets in the same callback, so when Streamlit reruns, these new values will be displayed. It’s a little convoluted, but once you get your head around it, its pretty powerful.

Thanks. Really helpful!

Any ideas how to make this work from within a st.form (given the states of widgets are committed on st.form_submit_button) ?

Add the callback to the submit button.

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