Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EventListener nested properties not working #279

Open
FRosner opened this issue Aug 3, 2023 · 4 comments
Open

EventListener nested properties not working #279

FRosner opened this issue Aug 3, 2023 · 4 comments

Comments

@FRosner
Copy link

FRosner commented Aug 3, 2023

Problem

I am trying to use an EventListener to handle clicks on some HTML buttons which are not dash components (because they are inside a data table and data tables don't support dash components 😢 ).

In order to know what dash code to call based on the button clicked, I want to make use of data attributes which contain information about the relevant python code to call and what data to pass (e.g. which row the button was in).

However, it seems that the property extraction code does not give me the full values, but only a subset. The logging debug output shows:

image

While in the callback I only get:

{'srcElement.attributes': {'0': {}, '1': {}, '2': {}, '3': {}, '4': {}}}

Here's the event with the relevant properties I'm interesting in:

CLICK_EVENT = {"event": "click", "props": ["srcElement.attributes"]}

Here's my relevant layout:

EventListener(events=[CLICK_EVENT], logging=True, id=EVENT_LISTENER_ID),
dcc.Store(id=EVENT_LISTENER_STORE_ID, data={}),

Here's the callback:

@dashapp.callback(
    Output(EVENT_LISTENER_STORE_ID, "data"),
    Input(EVENT_LISTENER_ID, "n_events"),
    State(EVENT_LISTENER_ID, "event")
)
def click_event(n_events, event):
    if event is None:
        raise PreventUpdate
    print(event)
    return ""

Alternatively, I tried requesting "srcElement.attributes.data-click.value" directly in the event, which works. Is there a way to get nested props?

@emilhe
Copy link
Owner

emilhe commented Aug 3, 2023

It looks like all values are captures (you get 5 values, and the list has length 5), but the content is empty. My first guess would be that the content is not JSON serializeable - could that be the case? Otherwise, could you post a MWE (i.e. a small piece of code that runs and demonstrates the issue), then I can do a bit more debugging.

@FRosner
Copy link
Author

FRosner commented Aug 3, 2023

My first guess would be that the content is not JSON serializeable - could that be the case?

It is a NamedNodeMap, maybe this is the issue indeed. https://stackoverflow.com/questions/25497475/html-attributes-to-json

Otherwise, could you post a MWE (i.e. a small piece of code that runs and demonstrates the issue), then I can do a bit more debugging.

I'm new to the ecosystem, is there some online dash playground I can use?

@FRosner
Copy link
Author

FRosner commented Aug 3, 2023

Alternatively, you can use the example from https://www.dash-extensions.com/components/event_listener

from dash_extensions.enrich import DashProxy, html, Input, Output, State
from dash_extensions import EventListener
from dash.exceptions import PreventUpdate

# JavaScript event(s) that we want to listen to and what properties to collect.
event = {"event": "click", "props": ["srcElement.attributes"]}
# Create small example app
app = DashProxy()
app.layout = html.Div([
    EventListener(
        html.Div("Click here!", className="stuff"),
        events=[event], logging=True, id="el"
    ),
    html.Div(id="log")
])

@app.callback(Output("log", "children"), Input("el", "n_events"), State("el", "event"))
def click_event(n_events, e):
    if e is None:
        raise PreventUpdate()
    return ",".join(f"{prop} is '{e[prop]}' " for prop in event["props"]) + f" (number of clicks is {n_events})"

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

@emilhe
Copy link
Owner

emilhe commented Aug 3, 2023

Yes, I believe that is indeed the issue. With the current implementation, you must "drill down" until you reach properties which are (trivially) JSON serializable, which is indeed the case for srcElement.attributes.data-click.value.

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

No branches or pull requests

2 participants