Phrogz
Phrogz

Reputation: 303441

Stop Plotly dash.dcc.Store() triggering an update on page load

Summary: my Dash app is triggering a callback on initial page load from a dcc.Store, with sometimes-old data in it. How do I prevent this? Note: I am using prevent_initial_call=True.

The layout for my Dash app contains these:

dcc.Location(id=self.url_id, refresh=False),
dcc.Store(id=self.getter_id, storage_type="session"),
dcc.Store(id=self.setter_id, data={}, storage_type="session"),

I have these callbacks:

@self.app.callback(
    Output(self.getter_id, "data"),
    Input(self.url_id, "hash"),
)
def parse_hash(hash_str: str | None = None) -> HashValues:
    return hash_to_dict(hash_str)

@self.app.callback(
    Output(self.url_id, "hash"),
    Input(self.setter_id, "data"),
    State(self.url_id, "hash"),
    prevent_initial_call=True,
)
def update_hash(
    set_hash_data: HashValues | None = None,
    current_hash: str | None = None,
) -> str:
    if not set_hash_data:
        raise dash.exceptions.PreventUpdate()
    # merge new settings over existing values
    params = hash_to_dict(current_hash) | set_hash_data
    return dict_to_hash(params)

99% of the time everything works fine. I can use (self.setter_id, "data") as an output for other callbacks on the page, the update_hash() callback is invoked and the url hash shows what I want. I can modify the URL on the page and callbacks using (self.getter_id, "data") are properly invoked with the parsed data sent to them.

However, when I request the route fresh, with no hash on the URL, the last callback above usually triggers, with set_hash_data being some dict…that is often NOT even the last dict I set it to. (As a result, the bogus data is sent up into the URL's hash, which then happens to trigger updates to various inputs all over the page. The "pristine" page that I tried to load fresh starts off in a bad state.)

As you can see, I have prevent_initial_call=True set for that callback. I've put breakpoints and print statements in every callback in my app. This is the first callback that triggers on page load. I've looked at the network trace in Chrome, and this the first call to _dash-update-component.

Any suggestions on how to fix this, or trace the offending JS?

Upvotes: 0

Views: 52

Answers (0)

Related Questions