Skip to content

Persistence does not work with Circular Callbacks #1856

Open
@RunQi-Han

Description

@RunQi-Han

persistence does not work in circular callbacks. See the example below:
This example is based on: "Synchronizing Two Checklists" from https://dash.plotly.com/advanced-callbacks

  • refreshing the page will clear the selection even when enabling presistence=True
import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

options = [
    {"label": "New York City", "value": "NYC"},
    {"label": "Montréal", "value": "MTL"},
    {"label": "San Francisco", "value": "SF"},
]
all_cities = [option["value"] for option in options]

app.layout = html.Div(
    [
        dcc.Checklist(
            id="all-checklist",
            options=[{"label": "All", "value": "All"}],
            value=[],
            labelStyle={"display": "inline-block"},
            persistence=True,
        ),
        dcc.Checklist(
            id="city-checklist",
            options=options,
            value=[],
            labelStyle={"display": "inline-block"},
            persistence=True,
        ),
    ]
)
@app.callback(
    Output("city-checklist", "value"),
    Output("all-checklist", "value"),
    Input("city-checklist", "value"),
    Input("all-checklist", "value"),
)
def sync_checklists(cities_selected, all_selected):
    ctx = dash.callback_context
    input_id = ctx.triggered[0]["prop_id"].split(".")[0]
    if input_id == "city-checklist":
        all_selected = ["All"] if set(cities_selected) == set(all_cities) else []
    else:
        cities_selected = all_cities if all_selected else []
    return cities_selected, all_selected

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

A current workaround is to use dcc.Store to store the selections:

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

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

options = [
    {"label": "New York City", "value": "NYC"},
    {"label": "Montréal", "value": "MTL"},
    {"label": "San Francisco", "value": "SF"},
]
all_cities = [option["value"] for option in options]

app.layout = html.Div(
    [
        dcc.Checklist(
            id="all-checklist",
            options=[{"label": "All", "value": "All"}],
            value=[],
            labelStyle={"display": "inline-block"},
            persistence=True,
        ),
        dcc.Checklist(
            id="city-checklist",
            options=options,
            value=[],
            labelStyle={"display": "inline-block"},
            persistence=True,
        ),
        html.Div(id='dummy-trigger'),
        dcc.Store(id='temp-store',storage_type="local")
    ]
)
@app.callback(
    Output("city-checklist", "value"),
    Output("all-checklist", "value"),
    Output('temp-store',"data"),
    Input("city-checklist", "value"),
    Input("all-checklist", "value"),
    Input('dummy-trigger',"children"),
    State('temp-store',"data"),
)
def sync_checklists(cities_selected, all_selected, dummy_trigger, stored_fitlers):
    ctx = dash.callback_context
    input_id = ctx.triggered[0]["prop_id"].split(".")[0]
    if input_id == "city-checklist":
        all_selected = ["All"] if set(cities_selected) == set(all_cities) else []
    elif input_id == "all-checklist":
        cities_selected = all_cities if all_selected else []
    else:
        cities_selected,all_selected = stored_fitlers
    return cities_selected, all_selected,[cities_selected, all_selected]

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3backlogbugsomething broken

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions