Loading States

Loading Component

Every component in dash_core_components or dash_html_components comes equipped with
a loading_state property. This property contains an is_loading boolean that tells you
if the component is loading. Additionally, the component_name and prop_name attributes
return the name of that component and the name of the property that is loading (i.e. “layout”). Component authors can use this property to determine what to
do if the component is still loading. Dash uses this prop in the Loading component to display spinners if a component is loading. This means you can use
the Loading component to wrap other components that you want to display a loading spinner for. Here’s an example of what that looks like:

# -*- coding: utf-8 -*-
import dash
import dash_html_components as html
import dash_core_components as dcc
import time

from dash.dependencies import Input, Output, State

app = dash.Dash(__name__)

app.layout = html.Div(
    children=[
        html.H3("Edit text input to see loading state"),
        dcc.Input(id="ls-input-1", value='Input triggers local spinner'),
        dcc.Loading(id="ls-loading-1", children=[html.Div(id="ls-loading-output-1")], type="default"),
        html.Div(
            [
                dcc.Input(id="ls-input-2", value='Input triggers nested spinner'),
                dcc.Loading(
                    id="ls-loading-2",
                    children=[html.Div([html.Div(id="ls-loading-output-2")])],
                    type="circle",
                )
            ]
        ),
    ],
)

@app.callback(Output("ls-loading-output-1", "children"), Input("ls-input-1", "value"))
def input_triggers_spinner(value):
    time.sleep(1)
    return value


@app.callback(Output("ls-loading-output-2", "children"), Input("ls-input-2", "value"))
def input_triggers_nested(value):
    time.sleep(1)
    return value


if __name__ == "__main__":
    app.run_server(debug=False)

Edit text input to see loading state

Please also check out the docs for the Loading component for more information on how to use the Loading component.

Check Loading States From Components

Aside from using the Loading component, you can check if a certain component
(either from dash_core_components or dash_html_components) is loading by checking the
data-dash-is-loading attribute set on that component’s HTML output. This means that
you can target those components yourself with CSS, and create your own custom loading
for them. Here’s an example of what that could look like:


# -*- coding: utf-8 -*-
import dash
import dash_html_components as html
import dash_core_components as dcc
import time

from dash.dependencies import Input, Output, State

app = dash.Dash(__name__)

app.layout = html.Div(
    children=[
        html.Div(id="cls-output-1", className='output-example-loading'),
        dcc.Input(id="cls-input-1", value="Input triggers local spinner"),
        html.Div(
            [
                html.Div(id="cls-output-2", className='output-example-loading'),
                dcc.Input(id="cls-input-2", value="Input triggers nested spinner"),
            ]
        ),
    ]
)


@app.callback(Output("cls-output-1", "children"), Input("cls-input-1", "value"))
def input_triggers_spinner(value):
    time.sleep(1)
    return value


@app.callback(Output("cls-output-2", "children"), Input("cls-input-2", "value"))
def input_triggers_nested(value):
    time.sleep(1)
    return value


if __name__ == "__main__":
    app.run_server(debug=False)

You could target all components in the layout above that are loading using the following CSS:

*[data-dash-is-loading="true"]{
    visibility: hidden;
}
*[data-dash-is-loading="true"]::before{
    content: "Loading...";
    display: inline-block;
    color: magenta;
    visibility: visible;
}

You can also target any other HTML attributes using CSS.
To target a specific class use the following CSS:

*[class="output-example-loading"][data-dash-is-loading="true"]{
    visibility: hidden;
}
*[class="output-example-loading"][data-dash-is-loading="true"]::before{
    content: "Loading...";
    display: inline-block;
    color: magenta;
    visibility: visible;
}