Button is firing on load and I want it to fire only on click

This piece of code:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State

app = dash.Dash()

app.layout = html.Div([
    dcc.Input(id='my-id', value='initial value', type='text'),
    html.Button(id='button', children='submit'),
    html.Div(id='my-div')
])


@app.callback(
    Output(component_id='my-div', component_property='children'),
    [Input(component_id='button', component_property='n_clicks')],
    [State(component_id='my-id', component_property='value')]
)
def update_output_div(n_clicks, input_value):

    print('hello from update output div')
    return 'You\'ve entered "{}" and n_clicks is {}'.format(input_value, n_clicks)


if __name__ == '__main__':

    app.run_server(debug=True,  port = 8060)

Is firing when the page loads for the first time, as I can see the output of the “update_output_div” callback function. How can I prevent this? I though by not providing “n_clicks” on the button, this should not be the case, but it is. This is on python2.7.

Right now in dash, the callbacks are always going to fire on page load. So, you’ll just need to check if n_clicks is 0 or None in your callback

Hi,

Thanks for your answer. You mean however n_clicks = None right? That’s the value I get on load.

I just want to share another method to fire only on click not on load. As it was mentioned, I usually check if n_clicks is None, but I’m working with an app that loads its content from a file and in this case n_clicks has a previous value that is used to keep track of the items inserted in a table. In this case what I did was to add an additional input that is also loaded with the button and check with callback_context if this input was triggered, in which case the action is prevented:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash import no_update

app = dash.Dash()

app.layout = html.Div([
    dcc.Input(id='my-id', value='initial value', type='text'),
    html.Button(id='button', children='submit'),
    html.Div(id='on-load', style={'display': 'none'}),
    html.Div(id='my-div')
])


@app.callback(
    Output(component_id='my-div', component_property='children'),
    [Input(component_id='button', component_property='n_clicks'),
    Input(component_id='on-load', component_property='children')],
    [State(component_id='my-id', component_property='value')]
)
def update_output_div(n_clicks, on_load, input_value):
    ctx = dash.callback_context
    # print(ctx.triggered)
    prop_id = ctx.triggered[0]['prop_id']
    # print(prop_id)
    if prop_id!='.':
        print('hello from update output div')
        return 'You\'ve entered "{}" and n_clicks is {}'.format(input_value, n_clicks)
    else:
        return no_update

if __name__ == '__main__':

    app.run_server(debug=True,  port = 8060)

You can also use prevent_initial_call=True

1 Like