Callbacks receive initial Null or NaN values and proper use of `PreventUpdate()` calls

This is my second question with using Plotly Dash. So far my app is working quite well. The docs are really quite helpful as well as online videos.

The one area that is a bit confusing is the initial behavior when starting up an app. I understand that when an app starts up, the asynchronous nation of web pages means that different controls come up at different times. I have some callbacks that refer to DCC.Store “data” components, and upon startup I started to get lots of Null or NaN values, until the actual Store came up in the layout and started to provide the expected data.

I ended up handling these Null or NaN values with conditional statement where I would do PreventUpdate() if the Store “data” value was null, otherwise process accordingly.

I was not sure if this was a good programming pattern to follow or not. I can imagine other programming patterns where I can set a setting and the Store will not produce values until it comes up, or the callback will not receive values until the data is in a certain from, like a Dictionary.

Hence I was wondering if there is a good place to look in the docs for a discussion on this question? Is there a good pattern to follow in these cases, or is what I am using the right way to go. I just figured I would check.

hi @krishnab ,

FYI, keywords are prevent_initial_call=True

import dash
from dash import html
from dash.dependencies import Input, Output
from datetime import datetime
import time

app = dash.Dash()

app.layout = html.Div(
    [
        html.Button("execute callbacks", id="button_2"),
        html.Div(children="callback not executed", id="first_output_2"),
        html.Div(children="callback not executed", id="second_output_2"),
        html.Div(children="callback not executed", id="third_output_2"),
        html.Div(children="callback not executed", id="fourth_output_2"),
    ]
)


@app.callback(
    Output("first_output_2", "children"),
    Output("second_output_2", "children"),
    Input("button_2", "n_clicks"), prevent_initial_call=True)
def first_callback(n):
    now = datetime.now()
    current_time = now.strftime("%H:%M:%S")
    return ["in the first callback it is " + current_time, "in the first callback it is " + current_time]


@app.callback(
    Output("third_output_2", "children"), Input("second_output_2", "children"), prevent_initial_call=True)
def second_callback(n):
    time.sleep(2)
    now = datetime.now()
    current_time = now.strftime("%H:%M:%S")
    return "in the second callback it is " + current_time


@app.callback(
    Output("fourth_output_2", "children"),
    Input("first_output_2", "children"),
    Input("third_output_2", "children"), prevent_initial_call=True)
def third_output(n, m):
    time.sleep(2)
    now = datetime.now()
    current_time = now.strftime("%H:%M:%S")
    return "in the third callback it is " + current_time


if __name__ == '__main__':
    app.run_server(debug=True)
1 Like

Thanks for the link @stu . I will read it in detail.

I tried that prevent_initial_call = True option, but it did not work in all cases. Like I believe it worked in some cases to prevent these Nulls, but I still found that a bunch were getting through. I am not sure if I just set some of these things up incorrectly, or if it was just the async nature of webpages? That was part of my confusion, since I followed the docs and sometimes I got the expected results but other times I did not.

I will continue to use that prevent_initial_call argument, but I found that I still had to use that PreventUpdate thing too. Do you have a sense of what it makes sense to use the PreventUpdate function versus the prevent_initial_call argument.

Do you know of any good examples with this stuff? I am writing some of my own demos to experiment, but there are so many combinations to try and it is hard to try them all.

I believe that if you provide an MRE, people here can help you more easily. :smile:

1 Like