Hello,
As the title say, I am using some dcc.Store as input in some callback, but it is not getting triggered.
My code is basically the next:
from dash import html, dcc, Input, Output, State, callback, clientside_callback, Dash
app = Dash(__name__)
app.layout = html.Div([
dcc.Store('ServerTriggerer', storage_type='session', data={'Value': None}),
dcc.Store('ClientTriggerer', storage_type='session', data={'Value': None}),
html.Div(
children=[
dcc.Dropdown(
options=['A', 'B', 'C'],
**{'id': 'Select_That_Triggers'} # I know I dont need the dict unpack, but id is a reserved function in python, so it bothers me to use it as key.
),
dcc.Dropdown(
options=[],
**{'id': 'Select_That_Receives_Values'}
)
]
)
])
server_trigger_js = """
function trigger_server(val, server_triggerer_data, client_triggerer_data){
console.log('Server triggerer called', val);
if (val === null){
client_triggerer_data['Value'] = val
return dash_clientside.no_update, client_triggerer_data;
}
server_triggerer_data['Value'] = val;
return server_triggerer_data, dash_clientside.no_update;
}
"""
client_update_dropdown_js = """
function update_dropdown(client_triggerer_data){
console.log('Update Dropdown called');
const options = client_triggerer_data['Value'];
return options;
}
"""
clientside_callback(
server_trigger_js,
Output('ServerTriggerer', 'data'),
Output('ClientTriggerer', 'data', allow_duplicate=True),
Input('Select_That_Triggers', 'value'),
State('ServerTriggerer', 'data'),
State('ClientTriggerer', 'data'),
prevent_initial_call=True
)
@callback(
Output('ClientTriggerer', 'data'),
Input('ServerTriggerer', 'data'),
State('ClientTriggerer', 'data'),
prevent_initial_call=True
)
def get_options_server(server_triggerer_data, client_triggerer_data):
print('server called')
OPTIONS_MAP = {'A': [1,2,3], 'B': [4,5,6], 'C': [7,8,9]}
selected_value = server_triggerer_data['Value']
options = OPTIONS_MAP[selected_value]
client_triggerer_data['Value'] = options
return client_triggerer_data
clientside_callback(
client_update_dropdown_js,
Output('Select_That_Receives_Values', 'options'),
Input('ClientTriggerer', 'data'),
prevent_initial_call=True
)
if __name__ == '__main__':
app.run(debug=True)
To simplify the understanding the flow is the next:
Input_A -- client: Stores Value --> Store_A -- server: gets_new_value_and_stores --> Store_B -- client: add_options_to --> Input_B
In case some condition is met:
Input_A -- client: Stores Value --> Store_B -- client: add_options_to --> Input_B
What happens now:
- First client function is called.
- First store is updated.
- Nothing else happens from here.
Thanks in advance.