Updating Event Listener Children using callback? Bug?

Hi,

I’m encountering what seems to be a bug with EventListener or perhaps I’m just not understanding it well enough.

tl;dr
I explicitly set the EventListener for clicks in the layout and specify the children to be a dropdown component which is already in the initial loading of the app, I then use a separate callback to dynamically update the EventListener children component - to my surprise - (1) it doesn’t update the children (seemingly because clicks to dropdown1 are still triggering eventlistener) and 2 all clicks on the page are firing the callbacks. Documentation says lack of child specification would cause this but … not sure why it would work out to this if it’s been specified.

See the MRE below and context why I can’t just bypass the EventListener and feed Input directly

import dash
from dash import html, dcc, Input, Output
from dash_extensions import EventListener
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__, suppress_callback_exceptions=True)
event = {"event": "click","props": ["srcElement.className", "srcElement.innerText"]} 
# Layout with the initial dropdown and EventListener
app.layout = html.Div([
    dcc.Dropdown(id='dropdown1', options=[{'label': i, 'value': i} for i in ['1dropdown', '2dropdown']], value='Option 1'),
    html.Div(id='dd2container'),
    html.Div(EventListener(id='listener1',events = [event],logging=True, children = 'dropdown1')),
    html.Div(id='log')
])

# Callback to dynamically update the EventListener children based on the selection in dropdown1
@app.callback(
    Output('dd2container', 'children'),
    Input('dropdown1', 'value')
)
def update_event_listener(value):
    if value == '2dropdown':
        # If Option 1 is selected, return dropdown2
        return html.Div(dcc.Dropdown(id='dropdown2', options=[{'label': i, 'value': i} for i in ['A', 'B']], value='A'))
    else:
        # If no option is selected, return an empty div
        return html.Div()

# Callback to handle events in dropdown2
@app.callback(
    Output('listener1', 'children'),
    Input('dropdown1', 'value')
)
def update_eventlistener(value):
    print("FIRED")
    if value:
        return "dropdown2"
    else:
        return "dropdown1"
    
@app.callback(
    Output('log', 'children'),
    Input("listener1", "n_events"),
)
def eventlistenertester(value):
    print("FIRED")
    if value:
        return "Number of Clicks{}".format(value)
    else:
        return "No Clicks"





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

Here’s the situation:
I have a dash app where I have 3 dropdowns - though the page initializes with just 1, selecting a value for dropdown 1 creates a 2nd dropdown and so on and so forth this is because the dropdown options are chained so to speak. These dropdowns feed callbacks that query databases and generate figures. I need to make them flexible enough such that they can generate the plots as soon as 1 of the dropdowns is selected.

Because so much of the layout is dynamically created, there’s a ton of div nesting and one consequence is that I can’t specify an input that is yet to be created. I have to rely on EventListener because for some reason one of my div containers isn’t firing a callback when the contents of the div container (a dcc.Dropdown selection) changes.

Thanks!

Never mind! I figured out a better fix. I bypassed eventlistener and just created a dcc.store element that was present in the initialization and updated the data for that component and that just turned out to be much easier.