Streamlit: Widget's new value goes to limbo with st.experimental_get/set_query_params

Created on 18 Nov 2020  路  3Comments  路  Source: streamlit/streamlit

Summary

I am using query_params to mirror state of widgets, so I am able to reproduce specific state with URL. I need to change state of each widget twice to get change.

Steps to reproduce

  1. Load state from URL with st.experimental_get_query_params
query_state = st.experimental_get_query_params()
  1. Set previous state as preselected value to st.radio
    select_options = ['All', 'Case ID', 'Cedant', 'Doc Type']
    if 'select_aggregation' in query_state:
        preselected_index = find_index(select_options, lambda item: item == query_state['select_aggregation'][0])
    else:
        preselected_index = 0
    select_aggregation = st.sidebar.radio(
        label='Group by:',
        options=select_options,
        index=preselected_index if preselected_index > -1 else 0
    )
  1. Store current value to query params
st.experimental_set_query_params(
        select_aggregation=select_aggregation
    )
  1. Go to view
  2. Click on different radio button from Group by group.

Expected behavior:

New value is selected in radio and also changed in query params

Actual behavior:

Nothing happens, at first.
Value is changed in radio and also in query params after second click.

Is this a regression?

No

Debug info

  • Streamlit version: 0.70.0
  • Python version: 3.8.5
  • Using pip and venv
  • OS version: Mac OS 10.14.6
  • Browser version: Chrome 86.0.4240.198 (Official Build) (x86_64)
bug

Most helpful comment

@tybirk-mindway Thank you, that's perfect. It helped a lot.

I did a few changes to mentioned workaround, because it was failing when app started with empty query params. If default query params were provided, then it worked like a charm.

query_state = st.experimental_get_query_params()
app_state = st.experimental_get_query_params()

session_state = SessionState.get(first_query_params=query_state)
first_query_params = session_state.first_query_params

if len(first_query_params.keys()) == 0:
    session_state.first_query_params = app_state

select_options = ["All", "Case ID", "Cedant", "Doc Type"]
preselected_index = eval(str(first_query_params["select_aggregation"][0])) if "select_aggregation" in app_state else 0
select_aggregation = st.sidebar.radio(
    label="Group by:",
    options=select_options,
    index=preselected_index if preselected_index > -1 else 0,
)

app_state['select_aggregation'] = [select_options.index(select_aggregation)]

st.experimental_set_query_params(**app_state)

So, as was mentioned here, I changed this

first_query_params = session_state.first_query_params
session_state = SessionState.get(first_query_params=query_params)

to this

session_state = SessionState.get(first_query_params=query_state)
first_query_params = session_state.first_query_params

and then I handled default state with empty query params

if len(first_query_params.keys()) == 0:
    session_state.first_query_params = app_state

Then my interpretation of this code

default_index = eval(first_query_params["radio"][0]) if "radio" in app_state else 0

was throwing and error, that arg 1 in eval should be string or etc. Integer was not fine. So I handled it with casting to string:

preselected_index = eval(str(first_query_params["select_aggregation"][0])) if "select_aggregation" in app_state else 0

And the last change. My code inspired by this line:

app_state["radio"] = radio_list.index(genre)

was implemented like this:

app_state['selected_runid'] = [runids_options.index(selected_runid)]

because otherwise state was an integer and not list.

I hope this will help somebody.

All 3 comments

I have the same behavior with custom React component, which sends new value for query params to main Python component.

Hi tomkomt,

I ran into the same problem - @karriebear describes why the behaviour happens and suggests a workaround here.

I made an example with a solution which goes a bit more in depth here. Hope it helps!

@tybirk-mindway Thank you, that's perfect. It helped a lot.

I did a few changes to mentioned workaround, because it was failing when app started with empty query params. If default query params were provided, then it worked like a charm.

query_state = st.experimental_get_query_params()
app_state = st.experimental_get_query_params()

session_state = SessionState.get(first_query_params=query_state)
first_query_params = session_state.first_query_params

if len(first_query_params.keys()) == 0:
    session_state.first_query_params = app_state

select_options = ["All", "Case ID", "Cedant", "Doc Type"]
preselected_index = eval(str(first_query_params["select_aggregation"][0])) if "select_aggregation" in app_state else 0
select_aggregation = st.sidebar.radio(
    label="Group by:",
    options=select_options,
    index=preselected_index if preselected_index > -1 else 0,
)

app_state['select_aggregation'] = [select_options.index(select_aggregation)]

st.experimental_set_query_params(**app_state)

So, as was mentioned here, I changed this

first_query_params = session_state.first_query_params
session_state = SessionState.get(first_query_params=query_params)

to this

session_state = SessionState.get(first_query_params=query_state)
first_query_params = session_state.first_query_params

and then I handled default state with empty query params

if len(first_query_params.keys()) == 0:
    session_state.first_query_params = app_state

Then my interpretation of this code

default_index = eval(first_query_params["radio"][0]) if "radio" in app_state else 0

was throwing and error, that arg 1 in eval should be string or etc. Integer was not fine. So I handled it with casting to string:

preselected_index = eval(str(first_query_params["select_aggregation"][0])) if "select_aggregation" in app_state else 0

And the last change. My code inspired by this line:

app_state["radio"] = radio_list.index(genre)

was implemented like this:

app_state['selected_runid'] = [runids_options.index(selected_runid)]

because otherwise state was an integer and not list.

I hope this will help somebody.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

randyzwitch picture randyzwitch  路  3Comments

nadgirsanket picture nadgirsanket  路  3Comments

matthew-trava picture matthew-trava  路  3Comments

kurt-rhee picture kurt-rhee  路  3Comments

RNogales94 picture RNogales94  路  3Comments