#Timeline comparables table
@app.callback(Output(‘memory-output-comparables’, ‘data’),
[Input(‘my-dropdown’, ‘value’)])
def filter_countries(deal_ids_selected):
if not deal_ids_selected:
# Return all the rows on initial load/no selected.
return comparablesList.iloc[-1:].loc[:, comparablesList.columns != ‘deal_id’].to_dict(‘rows’)
filtered = comparablesList.query('deal_id in @deal_ids_selected')
filtered = filtered.loc[:, filtered.columns != 'deal_id']
return filtered.to_dict('rows')
@app.callback(Output(‘comparablesTable’, ‘data’),
[Input(‘memory-output-comparables’, ‘data’)])
def on_data_set_table(data):
if data is None:
raise PreventUpdate
return data
#calculate delta
@app.callback(
Output(‘comparablesTable’, ‘data’),
[Input(‘comparablesTable’, ‘data_timestamp’)],
[State(‘comparablesTable’, ‘data’)])
def update_columns(timestamp, rows):
for row in rows:
try:
row[‘delta’] = float(row[‘lastPrice’]) ** 2
except:
row[‘delta’] = ‘NA’
return rows
You have already assigned a callback to the output
with ID “memory-output-timeline” and property “data”. An output can only have
a single callback function. Try combining your inputs and
callback functions together into one function.
Is there any way I can output two callbacks towards the same object? As in above… I cannot have two callbacks that assign something to comparablesTable
Only one callback per object/parameter pair is allowed. You can have one callback that handles setting the data
property of memory-output-timeline
and another that handles setting the value of another property of memory-output-timeline
. If you have multiple paths that would dictate the data
output to memory-output-timeline
, you need to set some conditional logic in one callback that would return the values accordingly.
Great thanks
Are you able to elaborate on conditional logic?
I have a datatable and for the callback there it fills the table with part of an SQL database
I also want a button to add additional rows afterwards, and I need to have calculations in the datatable as well
All these things require access to the datatable ‘data’ parameter
In another forum post (can’t recall which one), I found the following code snippet.
dash.callback_context.triggered[0]['prop_id'].split('.')[0]
This returns the ID of the input that triggered the callback. Here is a snippet that shows this:
@app.callback(
output=Output('data-container', 'children'),
inputs=[Input('SubmitButton', 'n_clicks'),
Input('OptionsButton', 'n_clicks')],
def poll_noaa_website_for_hilo_data(submit_clicks, options_click):
user_click = dash.callback_context.triggered[0]['prop_id'].split('.')[0]
callback_states=dash.callback_context.states.values()
callback_inputs=dash.callback_context.inputs.values()
if not user_click or user_click != 'SubmitButton':
# do something
else:
# do something else
Also, dash.callback_context.states.values()
provides current values of the states when the callback was triggered. dash.callback_context.inputs.values()
is the equivalent for inputs. I eventually combined all dash.callback_context
calls into a function for readability.
This is how it turned out
@app.callback(
Output('comparablesTable', 'data'),
[Input('addComparable', 'n_clicks'),
Input('memory-output-comparables', 'data')],
[State('comparablesTable', 'data'),
State('comparablesTable', 'columns')])
def route_comparables(data, n_clicks, rows, columns):
user_click = dash.callback_context.triggered[0]['prop_id'].split('.')[0]
callback_states = dash.callback_context.states.values()
callback_inputs = dash.callback_context.inputs.values()
if not user_click or user_click != 'addComparable':
if n_clicks > 0:
rows.append({i['id']: '' for i in columns})
return rows
else:
if data is None:
raise PreventUpdate
return data
It works for the most part except the adding of rows below, which is quite buggy. Only adds 5 rows at a time and deletes the data input from memory-output-comparables
if n_clicks > 0:
rows.append({i['id']: '' for i in columns})
return rows
The order of your input parameters are mismatched. Based on the ordering of @app.callback
, your function definition should be def route_comparables(n_clicks, data, rows, columns)
.
Also, if you are not using callback_states
and callback_inputs
, you can remove these lines…I just included them to illustrate how to check their status should this be helpful.
Hmmm doing that prevents the data to be loaded in the first place. I.e. the memory-output-comparables input doesn’t do anything
ok…Since your entire app code is not provided I can’t provide any further input. I just know the ordering of the callback params needs to match.
Just figured it out… had the incorrect input in my if statement
needed to have memory-output-comparables
1 Like