Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

callbacks watching dcc.Location's url.pathname fire twice on first page load #138

Closed
ned2 opened this issue Jan 3, 2018 · 4 comments
Closed

Comments

@ned2
Copy link
Contributor

ned2 commented Jan 3, 2018

When a callback targets dcc.Location's url.pathname, on the first page load (but not on the app load), I'm seeing that the callback is fired twice. The first time the pathname Input gets the value None, then on the second time it gets the correct current value from the URL.

Most of the time I'm comparing pathname against some string, so nothing bad happens and then the callback fires again and behaves correctly. However I can certainly imagine a scenario when the assumption that pathname is a string will make things break. Not to mention it's a little confusing when debugging.

@mjclawar
Copy link
Contributor

mjclawar commented Jan 3, 2018

This may be related to plotly/dash#133 and plotly/dash-renderer#24. (See specifically @chriddyp's comment here plotly/dash#133 (comment)).

We addressed it for our Dash applications by adding assert isinstance(pathname, str) so that the first request breaks with pathname as None. It unfortunately does cause the code to break, but at least it breaks immediately in the first callback that uses pathname, and then Dash handles the "correct" render in the request made immediately after the 500 error.

@chriddyp
Copy link
Member

chriddyp commented Jan 3, 2018

Yeah, this is sort of "intentional" although it is confusing. I think I explained it in my comments but another solution is to return with the loading state with:

if pathname is None:
    return 'Loading...'

I'm going to close this for now as this behaviour is pretty deeply ingrained in dash's front-end.

@chriddyp chriddyp closed this as completed Jan 3, 2018
@ned2
Copy link
Contributor Author

ned2 commented Jan 5, 2018

Yep for sure. I hadn't seen the discussion where you explain that, but it makes sense.

I think my preference for handling it (but obviously depends on the context) is to throw an exception for that request. If #190 goes in, then it's an even cleaner strategy.

@ngnpope
Copy link
Contributor

ngnpope commented May 4, 2018

So I bumped into this double triggering of callbacks and worked around it with an intermediate callback that did nothing. I didn't even need to raise PreventUpdate where the values of pathname, search or href were None.

Perhaps my attached simple example will be of use to someone: location-double-callback-workaround.py

Slightly related to this, I was messing around with query strings to perform actions, and found that I needed to change href and not pathname so that I could clear query strings when the action had been performed. This seemed to make things more prone to callbacks executing multiple times and I needed to use href as an input rather than pathname to order my callbacks correctly. This workaround also seemed to avoid extra callbacks in this case.

Edit: I should have emphasised that I had more than one callback listening for changes to pathname so serialising through this intermediate callback was much nicer than having to check pathname is None in all of them.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants