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.
query_state = st.experimental_get_query_params()
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
)
st.experimental_set_query_params(
select_aggregation=select_aggregation
)
New value is selected in radio and also changed in query params
Nothing happens, at first.
Value is changed in radio and also in query params after second click.
No
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.
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.
So, as was mentioned here, I changed this
to this
and then I handled default state with empty query params
Then my interpretation of this code
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:
And the last change. My code inspired by this line:
was implemented like this:
because otherwise state was an integer and not list.
I hope this will help somebody.