Callback parameter is created inside another callback

This won’t work. The output, inputs, and state arguments of a callback are used to build the webpage when run_server is called. After this point you may be able to change the Python code but it will break the interaction between the web page and the Python.

I have rewritten your code in a way that does not require dynamically changing the callback. It uses the recently announced dash.callback_context.triggered from 📣 Dash 0.38.0 released to figure out which input triggered the callback and respond appropriately.

import dash
from dash.dependencies import Input, Output # for user interface
import dash_core_components as dcc
import dash_html_components as html


app = dash.Dash(__name__)
app.layout = html.Div(children=[
    html.Div(dcc.Dropdown(id='select_input', options=[{'label': 'A', 'value': 'A'}, {'label': 'B', 'value': 'B'}])),
    html.Div([dcc.Input(id='text_input', type='text')]),
    html.Div(id='output1'),
    html.Div(id='output2'),
])


@app.callback(
    Output('output1', 'children'),
    [Input('select_input', 'value')],
)
def dropdown_options(select_input):
    if select_input is None:
        return html.P('please select')
    if select_input == 'A':
        return html.P(f'special is updated!')
    else:
        return html.P('special will not be updated.')


@app.callback(
    Output('output2', 'children'),
    [Input('select_input', 'value'), Input('text_input',  'value')]
)
def uploaded_files(option, special):
    if option is None:
        raise dash.exceptions.PreventUpdate
    if special is None:
        special = ''

    triggered_input = dash.callback_context.triggered[0]['prop_id']

    if option == 'A' and triggered_input == 'select_input.value':
        return html.P(f'You selected A, the length of text input is: {len(special)}')
    if option == 'A' and triggered_input == 'text_input.value':
        return html.P(f'You selected A and entered {special}')
    if option == 'B':
        return html.P(f'you have selected B, text will be ignored!')


if __name__ == '__main__':
    app.run_server()

It’s not exactly the behavior you describe but hopefully you should be able to get this approach to work as you want.

1 Like