3

I am providing below the snippets of child, parent and grandparent component, where the child is contained inside the parent component, and the parent is contained inside the grandparent component.

Child

<template>
    <a href="#" onclick={handleClick}>
        <lightning-layout vertical-align="center">
            This is some text
        </lightning-layout>
    </a>
</template>

export default class Child extends LightningElement {
    handleClick(event) {
        event.preventDefault();
        this.dispatchEvent(new CustomEvent('notification'), { bubbles: true, composed: true });
    }
}

Parent:

<template>
    <lightning-card title="EventWithData" icon-name="standard:logging">
        <c-child onnotification={handleNotification}></c-child>
    </lightning-card>
</template>

export default class Parent extends LightningElement {
    handleNotification(event) {
        console.log('This is parent');
    }
}

Grandparent:

<template>
    <c-parent onnotification={handleNotification}></c-parent>
</template>

export default class GrandParent extends LightningElement {
    handleNotification(event) {
        console.log('This is grandParent');
    }
}

I am getting the message from the parent component, signifying that the parent component can listen to the child event, but the grandparent can't listen to the event. Is there something which I am missing?

Please note that I have set the bubbles and composed property of the event as true.

  • 2
    As per the documentation you should pass like this new CustomEvent('notification', { bubbles: true, composed: true }) – vignesh Mar 6 '19 at 7:47
  • This is how I am passing. But still its not working. – snl Mar 12 '19 at 16:15
2

It works with bubble & composed set to true.

    // Event dispatch on Grand Child

    //Method to show selected tab upon user select
    selectTab(event) {
        event.preventDefault();
        this.dispatchEvent(new CustomEvent('selecttab', {bubbles: true, composed: true, detail :{ selectedIndex: this.tabIdVal}}));
    }

    // Event listener on Grand Parent

    constructor() {
        super();
        this.addEventListener('movetab', this.moveTab.bind(this));
        this.addEventListener('selecttab', this.selectTab.bind(this));      
    }
| improve this answer | |
0

You can only listen to the events fired by the immediate child. That is child's events can be listened by just parent and not a grandparent.

Check an excerpt from SF Docs:

We don’t recommend bubbling events outside of your own template, but it is possible. To bubble an event to the template that contains your component, dispatch the event on the host element. The event is visible only in the template that contains your component.

As your parent contains child, it can listen to the child's event. Your grandparent doesn't and hence cant listen to child's event.

| improve this answer | |
  • 1
    This is from the documentation::: If you configure an event with bubbles: true and composed: true, the event type becomes part of the component’s public API. It also forces the consuming component and all of its ancestors to include the event as part of their APIs. It's a big API contract to sign up for. If you do use this configuration, the event type should be globally unique. – snl Mar 12 '19 at 16:21
  • @snl were you able to achieve this using bubble and compose attributes? – devforce May 7 '19 at 15:08
  • No. You need to fire another event from parent component. – snl May 7 '19 at 15:16
0

I am able to this with 'bubble' and 'composed' to true with inline event handlers too.

this.dispatchEvent(new CustomEvent('alert', { bubbles: true,
                                              composed: true,
                                              detail: element.value }));

Here is the code snippet.

| improve this answer | |
0

I just spent a while scratching my head on this too.

This will compile, but the event won't be caught by any components other than the immediate parent:

this.dispatchEvent(new CustomEvent('notification'), { bubbles: true, composed: true });

This, however, will work:

this.dispatchEvent(new CustomEvent('notification', { bubbles: true, composed: true }));

Note the moved ) - in the first example the CustomEvent constructor is never given the bubbles and composed options, so they fallback to their default values of false

| improve this answer | |

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.