Display different components based on callback output condition

Is it possible to return different types of components based on what a callback returns?

app.layout = dbc.Placeholder(id="fill_it")

@app.callback(
    Output(
        dict(       #<-- single Output accepts a dict of possibilities
             "1st" = dict(  #<--- identifier
                 component_id = "fill_it", 
                 component_property = content
             ),
            "2nd" = dict(
                component_id = "fill_it",
                component_property = content
            )
        )
    ),
    Input(component_id='fill_dropdown', component_property='value')
)
def filler(value):
    if (value is None):
        key = "1st"
        content = _
    elif (value is not None):
        key = "2nd"
        content = _
    return key, content

Based on the returned key, a different element from the Output dict is rendered. Something like that. Or you could have a SubOutput(key).

The reason why I ask is that it feels like there are a lot of questions out there about making adjustments based on what the data layer returns:

I am pretty sure Jinja’s Python handlebars (static front end) can do this.

Or is there just supposed to be an if statement in the app.layout that changes which callback is fired based on the data? ~ logic in view

It’s a bit unclear to me what you are trying to do. In your example, you are always targeting the same element as output (with id fill_it). Is that intentional? Or is you intention to target different elements?

@Emil Yes, it is intentional. Based on the output of the callback, the fill_it component would be either a plot or a paragraph

i guess you could have multiple Outputs and the display property of them could change to hidden

So something like this (the content toggles between a paragraph and a plot on click)?

from dash import Dash, html, Output, Input, dcc

# Create small example app.
app = Dash(prevent_initial_callbacks=True)
app.layout = html.Div(
    [html.Button("Click me", id="btn"), html.Div(id="container")]
)

@app.callback(Output("container", "children"), Input("btn", "n_clicks"))
def update(n_clicks):
    condition = n_clicks % 2 == 0  # toggle on click
    if condition:
        return html.P("A paragraph")
    return dcc.Graph()

if __name__ == '__main__':
    app.run_server(port=8888)
2 Likes

Overwriting the children attribute of Div! :exploding_head:
thank you!