Thanks for the fast reply on a sunday!
I’ve implemented what is proposed in that post and the one I linked to before:
app = Dash()
.
.
.
@app.callback([Output('tabs', 'children')],[Input('button', 'n_clicks')])
def create_graph(n_clicks):
if(n_clicks is None):
#do nothing
else:
#create new dcc.Tab containing new dcc.Graph with id="plot"+str(n_clicks)
return #updated tabs children
def create_callback(retfunc):
"""creates a callback function"""
def callback(*input_values):
if input_values is not None and input_values!='None':
try:
retval = retfunc(*input_values)
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print('Callback Exception:',e,exc_type, fname, exc_tb.tb_lineno)
print('parameters:',*input_values)
return retval
else:
return []
return callback
dyn_func = create_callback(save_zoom)
[app.callback([Output('plot'+str(i), 'figure')],
[Input('plot'+str(i), 'relayoutData')],
[State('plot'+str(i), 'figure'),
State('tabs', 'value')]) (dyn_func) for i in range(2)]
But to me, this is essentially the same as creating the callbacks statically. Although I am technically creating them dynamically I still need to know beforehand the exact quantity of elements/callbacks that will be generated (Or at least the maximum amount in this case). Forcing me to constrain the user to a limited number of options.
I know for know it’s not possible to create callbacks at runtime, so I guess I’ll have to wait for an update : )
In Dash, all of the callback functions and decorators need to be defined up-front (before the app starts). This means that you must generate callbacks for every unique set of input components that could be present on the page.
This, by the way, is confusing to me. How am I getting a dash.exceptions.DuplicateCallbackOutput
(when the app has already started), as explained in the original post if it’s not possible to create callbacks after the app has started? @chriddyp
Thanks, looking forward to any updates on this!