Separate callbacks from callbacks

Is calling a callback within a callback still not possible? If so has anyone found some good examples of workarounds?

What I would like to do is have different tabs in my app with separate charts in each tab that have their own dropdowns that feed in values from callbacks.

Something like this in pseudo-code logic:

callback(choose tab)
  def output_figure:
      if choose tab == 3d scatter
         Divs for 3d scatter
         callbacks for 3d
         def output_3d
      elif choose tab == 2d scatter
         Divs for 2d scatter
         callbacks for 2d
         def output_2d

I have the tabs just hide and unhide divs

1 Like

You can just define them all upfront.

app.layout = html.Div([
    dcc.Dropdown(id='display', options=[...]),
    html.Div(id='output')
])

@app.callback(Output('output', 'children'), [Input('display', 'value')])
def display_output(value):
    if value == 'tab1':
         returm html.Div([
               dcc.Dropdown(id='tab1-dropdown')
               dcc.Graph(id='tab1-graph')
         ])
    elif value == 'tab1':
         returm html.Div([
               dcc.Dropdown(id='tab2-dropdown')
               dcc.Graph(id='tab2-graph')
         ])

@app.callback(Output('tab1-graph', 'figure'), [Input('tab1-dropdown', 'value')])
def update_graph1(value):
    ...

@app.callback(Output('tab2-graph', 'figure'), [Input('tab2-dropdown', 'value')])
def update_graph1(value):
    ...


1 Like

Thank you so much! I was able to get a working prototype off this logic.

1 Like

You’ll want to suppress callback exceptions because the callback functions will be bound to elements that don’t exist at app initialization.

app.config['suppress_callback_exceptions'] = True
1 Like

Thank you. What is the command that you use for making Divs hidden?

Assuming two <divs>: div-a & div-b within your html.Div(id='output'). You’d probably want something like

@app.callback(Output('div-a'), 'style'),
              [Input('tabs', 'value')])
def display_a(value):
    '''Switch tabs display while retaining frontend client-side'''
    if value == 'a':
        return {'display':'inline'}
    elif value == 'b':
        return {'display':'none'}
    else:
        return {'display':'none'}

@app.callback(Output('div-b'), 'style'),
              [Input('tabs', 'value')])
def display_b(value):
    '''Switch tabs display while retaining frontend client-side'''
    if value == 'b':
        return {'display':'inline'}
    elif value == 'a':
        return {'display':'none'}
    else:
        return {'display':'none'}