[SalesForce] Capturing event from LWC in Aura Component

I am just learning LWC and have some proplems wrapping my mind around event propagation. I have a Lightning Web Component that dispatches a "submitsuccess" event that should be handled by the LWC's container (which is an aura component). However, I am unable to properly register the event handler in the container component.

Here's my code:

<!-- child component that dispatches the event -->
<template>
    <lightning-record-edit-form object-api-name="Angebotsvariante_Position__c" onsuccess={handleRecordInsertNotify}>
   ...
   </lightning-record-edit-form>
</template>
// handler in the child component
handleRecordInsertNotify(event) {

    event.preventDefault();
    // create custom bubbling submit event that can be received from the parent component
    const successEvent = new CustomEvent('submitsuccess', {
        bubbles: true,
        composed: true
    });
    this.dispatchEvent(successEvent);
}
// the dynamic javascript in the aura container that is expected to react
$A.createComponent(
    'c:myCustomChild',
    {
        quoteVariationId: angebotsvarianteId
    },
    function(newCustomPosCreate, status, errorMessage) {
        if (status === 'SUCCESS') {

            // register an event listener at the main component, that catches the success event and closes the overlay
            component.addEventHandler(
                'submitsuccess',
                function(event) {
                    console.log('Event has been caught');
                }
            );

            // put the custom position create as custom modal in the overlay lib
            component.find('overlayLib').showCustomModal({
                body: newCustomPosCreate,
                showCloseButton: true,
                closeCallback: function() {
                    // some helper code
                }
            });

        } else {
            console.log('Status: ' + status);
            console.log('Errors: ' + errorMessage);
        }
    }
);

The function in addEventHelper never fires. However, debug logs seem to indicate, that the event has been dispatched.
Im still a beginner with events and LWC (lightning components in general).

All I want to achieve is to close the modal popup after a record has been successfully submitted (hence the "onsuccess" event handler). If there is an easier way, please tell me!

Best Answer

You can add event listener like below:

$A.createComponent(
        'c:myCustomChild',
        {
            onsubmitsuccess: component.getReference("c.handleSubmitSuccess"),
            quoteVariationId: angebotsvarianteId
        },
        function(newCustomPosCreate, status, errorMessage) {
            if (status === 'SUCCESS') {
                // -------- process callback-------------                    
            } else {
                console.log('Status: ' + status);
                console.log('Errors: ' + errorMessage);
            }
        }
    );

Now implement handleSubmitSuccess

handleSubmitSuccess : function(component, event, helper) {
    console.log('Event has been caught');
    //if you are passing data in detail of event
    //console.log(event.getParam("--data--"));
}

Additional info: In LWC, there is no concept of creating event component/register-event/handler-event.

You just dispatch event like this:

this.dispatchEvent(new CustomEvent('myevent', {
    detail: {
        data: someData
    }
}));

to handle this in parent LWC component:

<c-child-comp onmyevent={handleEvent}></c-child-comp>

to get the data from event in handler

handleEvent = event => { let myData = event.detail.data; }

For parent AURA component:

<c:childComponent onmyevent="{!c.handleEvent}"></c:childComponent>

to get data in handler:

handleEvent(cmp,event){ let myData = event.getParam('data'); }

Note: 1. You can also use addEventListener. But I think above method is less confusing.
2. Use bubble, composed and cancellable carefully. Read documentation before using them.
3. When you dispatch custom event, you need to add "on" before event name/type if you are handling event directly during declaration. Or else if you are using addEventListener in parent component javascript, you need to use event name as is.

Related Topic