[SalesForce] lightning:overlayLibrary and fire event issue

Fails

I have a lightning component (TestParent). The component has <lightning:overlayLibrary> which shows another component called TestChild. When I fire an event from TestChild it doesn't catched by TestParent and alert is not shown.

TestParent.cmp

<aura:component description="TestParent" implements="force:appHostable">
    <aura:handler name="fromModal" event="c:GeneralEvt"
                  action="{!c.fromModal}" />

    <lightning:button label="ShowModal"
                      onclick="{!c.showModal}" />

    <lightning:overlayLibrary aura:id="overlayLib"/>
</aura:component>

TestParentController.js

({
    showModal: function (component, event, helper) {
        $A.createComponent("c:TestChild", {},
            function(content, status, error) {
                if (status === "SUCCESS") {
                    component.find('overlayLib').showCustomModal({
                        header: "Child",
                        body: content,
                        showCloseButton: true
                    });
                } else {
                    throw new Error(error);
                }
            });
    },

    fromModal: function (component, event, helper) {
        alert('from modal');
    }
});

TestChild.cmp

<aura:component description="TestChild">
    <aura:registerEvent name="fromModal" type="c:GeneralEvt"/>

    <lightning:button label="Call Parent"
                      onclick="{!c.callParent}" />
</aura:component>

TestChildController.js

({
    callParent: function (component, event, helper) {
        var evt = component.getEvent('fromModal');
        evt.fire();
    }
});

Works

If I instead of usage of <lightning:overlayLibrary> add the child component to a {!v.body} of TestParent then event catched properly and I can see the alert.

TestParent.cmp

<aura:component description="TestParent" implements="force:appHostable">
    <aura:handler name="fromModal" event="c:GeneralEvt"
                  action="{!c.fromModal}" />

    <lightning:button label="ShowModal"
                      onclick="{!c.showModal}" />

    {!v.body}
</aura:component>

TestParentController.js

({
    showModal: function (component, event, helper) {
        $A.createComponent("c:TestChild", {},
            function(content, status, error) {
                if (status === "SUCCESS") {
                    component.set('v.body', content);
                } else {
                    throw new Error(error);
                }
            });
    },

    fromModal: function (component, event, helper) {
        alert('from modal');
    }
});

GeneralEvt.evt

<aura:event type="COMPONENT" description="GeneralEvt">
</aura:event>

How to make <lightning:overlayLibrary> send events properly?

Best Answer

Its a special case where in the parent won't listen to child's event, for doing so you would need to pass the reference of parent controller's method while creating it.

So add attributes here:

$A.createComponent("c:TestChild", {},

like:

$A.createComponent("c:Child_213329", {
    "fromModal": component.getReference("c.fromModal")
},

With parent event would be binded and called whenever parent fires that specific event.

Note: I might be missing something; looks like some kind of bug in lightning:overlayLibrary It just doesn't works the first time popup is opened but works afterwards.


Passing parameter to parent:

Add params to the component event, TestChildController.js-

({
    callParent: function (component, event, helper) {
        var evt = component.getEvent('fromModal')
            .setParams({
                "message" : "A component event fired me. " +
                "It all happened so fast. Now, I'm here!" })
            .fire();
    }
});

Get parameter in TestParentController.js-

fromModal: function (component, event, helper) {
    var message = event.getParam("message");
    console.log('message from modal', message);
}

Complete code used for testing/demo.

Related Topic