0

I was trying to implement event bubbling based on what the documentation says. For the scenario, where we mark bubbles as true and dispatch events to the element for the template where the event occurred( child component in our scenario).

As per documentation:

// myComponent.js
this.template.querySelector('div')
    .dispatchEvent(
        new CustomEvent('notify', { bubbles: true })
);

It says: The event must be handled in myComponent.js. Handlers in the containing component don’t execute because the event doesn’t cross the shadow boundary.

Now, below is my code :

Child Component: HTML:

<template>
    <div class="whiteBg" onpress={outerHandler}>
        <h1>Child Component</h1>
        <button class="slds-button slds-button_brand" onclick={handleClick}>Click Me!! </button>
    </div>
</template>

JS:

import { LightningElement } from 'lwc';

export default class BubblesTrue extends LightningElement {
    handleClick(){
        // eslint-disable-next-line no-console
        console.log('handleClick');
        const evt = new CustomEvent('press',{bubbles : true});
        this.template.querySelector('div').dispatchEvent(evt);
    }
    outerHandler(){
        // eslint-disable-next-line no-console
        console.log('outerHandler Child');
    }
}

Parent Component: HTML:

<template>
    <lightning-card title="Parent Component - Bubbles!!">
        <div >
            <p>This is Parent Component's template</p>
        </div>
        <div onpress={outerHandler}>
            <c-bubbles-true onpress={innerHandler}></c-bubbles-true>
        </div>
    </lightning-card>
</template>

JS:

import { LightningElement } from 'lwc';

export default class ParentBubblesTrue extends LightningElement {
    innerHandler(){
        // eslint-disable-next-line no-console
        console.log('Inner Handler');
    }
    outerHandler(){
        // eslint-disable-next-line no-console
        console.log('Outer Handler')
    }
}

Output:

enter image description here

Now, that I'm using this.template and not this.dispatchEvent, I'm not sure why the parent's handler is getting called? Documentation says that if we use it this way - the shadow boundary won't be passed. Can someone please help me understand this?

1
import { LightningElement } from 'lwc';

export default class BubblesTrue extends LightningElement {
    handleClick(){
        // eslint-disable-next-line no-console
        console.log('handleClick');
        const evt = new CustomEvent('press',{bubbles : true});
        // THIS ROW IS YOUR ISSUE
        this.template.querySelector('div').dispatchEvent(evt);
    }

    outerHandler(){
        // eslint-disable-next-line no-console
        console.log('outerHandler Child');
    }
}

You should be using this.dispatchEvent if you are wanting to dispatch a component event. The elements inside the component are not able to pass up that event since the event is generated from your template (component).

the proper syntax for this would look like this:

this.dispatchEvent( new CustomEvent( 'press', { bubbles: true, composed: true, detail: { value: 'Some value from my event' }}));

this.dispatchEvent will launch an event from your component and will be accessible by the on<eventname> keyword within your component tag ( onpress will reference the press CustomEvent )

You can also fire and listen to application level events using pubsub to add listeners, or fire listeners (https://github.com/trailheadapps/lwc-recipes/tree/master/force-app/main/default/lwc/pubsub)

Try this Trailhead here to get some better understanding for using the events and handling them:

https://trailhead.salesforce.com/en/content/learn/modules/lightning-web-components-basics/handle-events-in-lightning-web-components

Also for further reference on dispatching events: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.events_create_dispatch

| improve this answer | |
  • I'm talking about the example for 'bubbles : true' and 'composed:false'.. Documentation says - Handlers in the containing component don’t execute because the event doesn’t cross the shadow boundary. This is because we're using this.template.dispatchEvent and not this.dispatchEvent along with composed as false... However, the parent component is still able to listen to the event which shouldn't be the case as per documentation and that's exactly my question that why is the parent component able to listen to my event. – Ashutosh Arora Apr 6 at 7:20
  • if you inspect your HTML, the shadow boundary is likely appearing where? it sounds to me on the containing component where the shadow boundary is located. – Ronnie Apr 6 at 12:57
  • i'm assuming that you are referring to this example: developer.salesforce.com/docs/component-library/documentation/… – Ronnie Apr 6 at 12:58
  • Yes, the above url points to the example I'm referring to. bubbles: true and composed: false - example for this scenario.. – Ashutosh Arora Apr 7 at 14:08
  • Maybe this will add to it, though i think it is more aligned with the documentation: salesforce.stackexchange.com/questions/301140/… – Ronnie Apr 7 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.