dcc.Loading still showing when returning dash.no_update in callback

Hello,

I have a dcc.Loading() which contains a graph. This graph is updated through some user interactions but also through a dcc.Interval().

The issue comes when I sometimes need to ignore the callback if it’s triggered by the dcc.Interval(). Which I do by filtering the callback trigger and returning dash.no_update in a specific case.

However, the dcc.Loading animation still displays at each interval and the graph flickers even though I am returning dash.no_update

Here is a simplified sample code of what I have:

Layout

        dcc.Interval(
            id = 'graph-update',
            interval = 4000,
        ),
        dcc.Loading(
            id = "loading",
            children=[
                dcc.Graph(
                    id = 'plot',
                ),
            ]
        ),

Callback

        @app.callback(
            [
                Output('plot', 'figure'),
            ],
            [
                Input('graph-update', 'n_intervals')
            ],
            [
                State('plot', 'figure'),
            ],
        )
        def update(self, n, figure):

            ctx = dash.callback_context
            trigger_id = ctx.triggered[0]["prop_id"].split(".")[0]

            if (trigger_id == 'graph-update'):
                # raise dash.exceptions.PreventUpdate
                return dash.no_update

            return [figure]

How can I stop the dcc.Loading() component from showing when the callback function returns dash.no_update?

I have also tried raising an exception instead of returning dash.no_update but the result is the same.

Thank you

You use a serverside callback which induces delay due to communication between the client (probably your browser) and the server your dash app runs on. The loading animation will show for as long as your client needs to receive the no_update.

I am having the same problem, but I am using PreventUpdate. Is there any way to get rid of this Loading delay? For example by having some kind of condition before showing the loading component?

Hi, I had the same problem with dash ag-grid table, and I solved that by dcc.Loading(target_components=…).
The idea is to call dcc.Loading not for dcc.Graph, but for another layout component. I made a simple example that shows realization.

from random import random

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

app = dash.Dash(
    __name__,
    update_title=None,  # in order don't show loading instead of default title
)

figure = {
    'data': [
        {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
        {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': 'Montréal'},
    ],
    'layout': {
        'title': 'Dash Data Visualization'
    }
}

app.layout = html.Div([
    dcc.Loading(id="loading",
                children=[
                    html.Div(dcc.Graph(id='plot')),
                    html.Div(id='loading_trigger', hidden=True),
                ],
                target_components={'loading_trigger': 'children'},
                delay_hide=1000,  # imitate approximately time graph is loading
                fullscreen=True
                ),
    dcc.Interval(
        id='interval-component',
        interval=3 * 1000,  # Interval in milliseconds (3 seconds)
        n_intervals=0  # Start with 0 intervals
    )
])


@app.callback(
    Output('plot', 'figure'),
    Input('interval-component', 'n_intervals'),
    State('plot', 'figure'),
)
def update_output(_, fig):
    return figure


@app.callback(
    Output('loading_trigger', 'children'),
    Input('loading_trigger', 'children'),
)
def call_loader(_):
    return random()


# Run the app
if __name__ == '__main__':
    app.run_server(port=6785)

P.S. I replied on the post with the same problem, and forum doesn’t allow me to use the same msg body, so I added this ps.