dash icon indicating copy to clipboard operation
dash copied to clipboard

[BUG] dcc.Location callback fires twice IDENTICALLY

Open schmidt-jake opened this issue 5 years ago • 27 comments

As far as I can tell, this flavor of the "duplicate dcc.Location callback" issue (#883) hasn't been documented yet. When I run a multipage app, reloading the page fires the callback twice with the same href / pathname / search payload. This is distinct from the other issue of having the callback return None and then returning the proper value(s).

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

navbar = dbc.NavbarSimple(
    brand='Frac Planning App',
    brand_href='/',
    sticky='top',
)

body = dbc.Container(
    dbc.Row(
        dbc.Col(id='page-content')
    )
)

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    navbar,
    body
])

@app.callback(Output('page-content', 'children'),
              [Input('url', 'href')],
              [State('url', 'pathname'), State('url', 'search')])
def display_page(href, pathname, search):
    print('HREF:', href)
    print('PATHAME:', pathname)
    print('SEARCH:', search)
    url = urllib.parse.urlparse(href)
    # print('RAW pathname:', url)
    print('TRIGGER(S):', [i['prop_id'] for i in dash.callback_context.triggered])
    if url.path == '/':
        return form.layout
    elif url.path == '/result':
        query = dict(urllib.parse.parse_qsl(url.query))
        return result.plot(**query)
    else:
        raise dash.exceptions.PreventUpdate

Here is the output. It doesn't always print in the same order:

HREF: http://houmedge201:5004/
PATHAME: /
HREF: http://houmedge201:5004/
SEARCH: 
PATHAME: /
TRIGGER(S): ['url.href']
SEARCH: 
TRIGGER(S): ['url.href']

Running on Linux. Versions used:

dash                       1.7.0
dash-core-components       1.6.0
dash-html-components       1.0.2
dash-renderer              1.2.2

I've tried the fix mentioned in https://github.com/plotly/dash/issues/883#issuecomment-529469985 to no avail. Solving this is mission critical for my app because the duplicate callback crashes a subsequent database query.

Changing href via a html.Link makes the callback fire only once. However, users need to be able to share app URLs with query params, which right now is broken due to this bug.

schmidt-jake avatar Dec 16 '19 20:12 schmidt-jake

Is anyone else experiencing this issue?

schmidt-jake avatar Jan 02 '20 17:01 schmidt-jake

🙋‍♂️

landert avatar Jan 03 '20 07:01 landert

Me as well

abogaard avatar Jan 05 '20 09:01 abogaard

Same

bfaivre avatar Jan 16 '20 22:01 bfaivre

me too!

judithbach avatar Jan 30 '20 09:01 judithbach

me too. I tried to avoid the second time execution by using a data_store flag but for some reason, as the states and inputs are exactly the same, this can't be accomplished

davidolmo avatar Feb 04 '20 17:02 davidolmo

I am experiencing the same issue. Callback with a 'pathname' property as input is being triggered 4 times. The result is that a chart on another page takes a few seconds to appear rather than appear instantly when I click on the button for that page. Critical issue.

usser123 avatar Feb 11 '20 09:02 usser123

I'm experiencing this issue too. Digging a bit in the source code, it seems a dash-renderer problem with some components default state. Here is a quick fix to avoid this problem in Location component (https://github.com/jgoday/dash/commit/5681290f377832238d5734f6dd2409f1d7a3b097).

Need to figure out why this is happening with the location component anyway, maybe the real problem resides in dash-core-components/src/components/Loading.react.js ...) :thinking:

jgoday avatar Feb 18 '20 22:02 jgoday

Is anyone else experiencing this issue?

Me too.

danjdo avatar Feb 21 '20 17:02 danjdo

I'm having the same issue on dash 1.9.1.

ndepal avatar Mar 27 '20 19:03 ndepal

Having the same issue here unfortunately

BrunoGomesCoelho avatar Mar 31 '20 00:03 BrunoGomesCoelho

Yup, I also get this, very frustrating. Its not firing twice... its a single click on a dcc.Link is firing the change callback EIGHT times. A click on the daily dashboard, ventilation and back to daily gives the following console output:

@app.callback(Output("fluidContainer", "children"), [Input("url", "pathname")])
def display_dashboard(pathname):
    print(pathname)
    return locations.get(pathname)

Gives:

/daily
/daily
/daily
/daily
/daily
/daily
/daily
/daily
/daily
/daily
/ventilation
/ventilation
/ventilation
/ventilation
/ventilation
/ventilation
/ventilation
/ventilation
/ventilation
/ventilation
/daily
/daily
/daily
/daily
/daily
/daily
/daily
/daily
/daily
/daily

Samreay avatar Mar 31 '20 02:03 Samreay

I'm facing exactly same situation than Samreay, anyone found the root cause? I've tried with both href and pathname as input but still same behaviour..

pererumbo avatar Apr 07 '20 13:04 pererumbo

I tried the first example on the documentation page: http://dash-docs.herokuapp.com/urls On page reload, the callback runs twice. 04/10/2020: Continues with Dash v1.11.0.

wvwhome avatar Apr 08 '20 19:04 wvwhome

4/17/2020: However, Dash 1.11 is a great improvement over Dash 1.10 for chained callbacks with dcc.Location. I have a program with three callbacks. For the page load with Dash 1.10 the sequence was: 3, 2, 1, 1, 3, 2, 3. With Dash 1.11 the sequence is: 1, 1, 2, 3. So much better. I have a dozen other programs with similar improvements. 9/3/2020: Dash 1.16 fixes most of theses issues for my programs -- major improvement.

wvwhome avatar Apr 17 '20 13:04 wvwhome

Same here. I am going to watch this issue.

Thank you for the awesome job with Dash, by the way.

rafaelqntn avatar May 01 '20 02:05 rafaelqntn

Yes please On Thu, Apr 30, 2020, 11:00 PM Rafael Quintana [email protected] wrote:

Same here. I am going to watch this issue.

Thank you for the awesome job with Dash, by the way.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/plotly/dash/issues/1049#issuecomment-622225049, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABKCM2O5N5XTKYNRGC5ZWVLRPI3MHANCNFSM4J3PPKIQ .

tjmcdono avatar May 01 '20 08:05 tjmcdono

same here

hcai avatar Jun 01 '20 23:06 hcai

any updates here? I am currently building a tool based on dash and I have a long process which is triggered by a callback - unfortunately this callback is triggered twice: so now I have to wait extra long for the output

ghost avatar Jun 16 '20 01:06 ghost

+1

rusiano avatar Jun 16 '20 14:06 rusiano

Same issue here, when reading a cookie :/ waste of time and resource. Wondering if this is on the official fixit list for Plotly...

pkstacey avatar Aug 21 '20 16:08 pkstacey

I thought I had a workaround using an lru_cache, but it actually doesn't help that much, as the handler gets called multiple times before the first response gets returned.

grahamegee avatar Nov 01 '20 14:11 grahamegee

+1

Hootie9lives avatar Apr 16 '21 03:04 Hootie9lives

Having the same problem, no fix for this?

Paulito123 avatar May 22 '21 13:05 Paulito123

Is there any fix? Or a workaround for this available?

TashaStenner avatar Nov 03 '21 15:11 TashaStenner

I'm still having this issue with dash 2.3.1, did anybody find working solution?

Stayermax avatar May 25 '22 13:05 Stayermax

@alexcjohnson @T4rk1n sorry for the personal tag, but thought it might be useful to make sure that this issue has some more visibility and is on the roadmap.

I assume its been buried in the backlog in the last two years, but seems like its still an issue for many users.

Samreay avatar May 25 '22 13:05 Samreay

Still present in dash 2.6.1 :(

luggie avatar Oct 17 '22 13:10 luggie

Thankfully there's streamlit instead now to develop in. How can it be three years, a javascript fix posted, and direct dev tags, but not even a comment from any of the core team?

Samreay avatar Oct 17 '22 23:10 Samreay

Hey @Samreay, @luggie, or @Stayermax, do you have a minimal reproducible example of a Dash app that exhibits the Location callback firing twice?

Looking back through the history of the issue, I can't actually find any code that can be used to reproduce the issue, which makes triage/diagnosis of the problem difficult. There are likely other possible causes of duplicate callbacks firing based on custom code/env setup, which would need to be eliminated from possibility.

I had a a go at creating a minimal reproducible example from the original post (which itself was not reproducible), but don't see the behaviour. Do you in your setup? or does the example need to be changed?

from dash import Dash, html, dcc, Input, State, Output

app = Dash(__name__)

app.layout = html.Div([html.Div(id="page-content"), dcc.Location(id="url")])


@app.callback(
    Output("page-content", "children"),
    Input("url", "href"),
    State("url", "pathname"),
    State("url", "search"),
)
def display_page(href, pathname, search):
    print("HREF:", href)
    print("PATHAME:", pathname)
    print("SEARCH:", search)
    if pathname == "/":
        return html.Div(f"HOME - Search: {search}")
    return html.Div(f"{pathname} - Search: {search}")


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

ned2 avatar Oct 20 '22 16:10 ned2