dash icon indicating copy to clipboard operation
dash copied to clipboard

[BUG] dcc.Store callback firing multiple times

Open devmcp opened this issue 5 years ago • 2 comments

Describe your context

dash                      1.9.1               
dash-bootstrap-components 0.8.3               
dash-core-components      1.8.1               
dash-daq                  0.4.0               
dash-html-components      1.0.2               
dash-renderer             1.2.4               
dash-table                4.6.1               
- OS: MacOS 10.15.3
- Browser: Safari 
- Version 13.0.5

Describe the bug

The dcc.Storage component seems to trigger twice (sometimes more) on starting the app and sometimes on subsequent triggers. See example below.

Minimal working example code:

import dash

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

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Store(id='local', storage_type='local'),
    html.Div(html.Button('localStorage', id='local-button')),
    html.Div(0, id='local-clicks'),
])


@app.callback(Output('local', 'data'),
              [Input('local-button', 'n_clicks')],
              [State('local', 'data')])
def on_click(n_clicks, data):
    if n_clicks is None:
        raise PreventUpdate

    app.logger.info(f"Updating data store")

    data = data or {'clicks': 0}

    data['clicks'] = data['clicks'] + 1
    return data


@app.callback(Output('local-clicks', 'children'),
              [Input('local', 'modified_timestamp')],
              [State('local', 'data')]
              )
def on_data(ts, data):
    if ts is None:
        raise PreventUpdate

    app.logger.info(f"New data found! ({ts}, {data})")

    return f"{ts}, {data['clicks']}"


if __name__ == '__main__':
    app.run_server(debug=True, port=8077, threaded=True)

Example output:

Running on http://127.0.0.1:8077/
Debugger PIN: 597-637-135
New data found! (1584011957193, {'clicks': 24})
New data found! (1584011957193, {'clicks': 24})
Updating data store
New data found! (1584012443177, {'clicks': 25})
New data found! (1584012443177, {'clicks': 25})
Updating data store
New data found! (1584012445159, {'clicks': 26})
New data found! (1584012445159, {'clicks': 26})

Expected behavior

The callback should fire once.

devmcp avatar Mar 13 '20 14:03 devmcp

I also faced the same issue with my dcc.store(). I update the store in a client-side call and then call the server callback. here's a version inspired by your example.

Version Informations

dash                      2.4.1                    pypi_0    pypi
dash-core-components      2.0.0                    pypi_0    pypi
dash-html-components      2.0.0                    pypi_0    pypi
dash-daq                  0.5.0                    pypi_0    pypi

Reproduce the Bug.

import datetime
import dash
from dash import html, dcc
from dash.dependencies import Output, Input, State
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Store(id="local", storage_type="local"),
        html.Div(html.Button("localStorage", id="local-button")),
        html.Div(0, id="local-clicks"),
    ]
)

app.clientside_callback(
    """
    function(n_clicks, data) {
        if (n_clicks) {
            console.log("Updating data store");
            data = data || {clicks: 0};
            data.clicks = data.clicks + 1;
            return data;
        }
    }
    """,
    Output("local", "data"),
    [Input("local-button", "n_clicks")],
    [State("local", "data")],
)


@app.callback(
    Output("local-clicks", "children"),
    [Input("local", "modified_timestamp")],
    [State("local", "data")],
)
def on_data(ts, data):
    print(datetime.datetime.now())

    print(f"New data found! ({ts}, {data})")
    print("-" * 20)
    return f"{ts} - {data['clicks']}"


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

Expected Output

2022-06-25 15:22:20.186572
New data found! (1656150740170, {'clicks': 85})
--------------------

Current Output

Screenshot 2022-06-25 at 3 22 25 PM

and in the browser console

Screenshot 2022-06-25 at 3 22 33 PM

Karan-S-Mittal avatar Jun 25 '22 09:06 Karan-S-Mittal

Please help, is someplace I can look at if to resolve this.

Karan-S-Mittal avatar Jun 25 '22 09:06 Karan-S-Mittal