How to close lightning:overlayLibrary custom modal?

I was having some trouble getting the notifyClose function to work as well. If you base your code off the samples here, you'll be tempted to use the same local ID for multiple lightning:overlayLibrary declarations. That doesn't seem to work reliably.

I found I had to do something like this:

in the parent component which will launch the modal:

<lightning:overlayLibrary aura:id="overlayLib1"/>

in that component's helper where showCustomModal is called

component.find('overlayLib1').showCustomModal({...

in the modal's component containing buttons which will trigger closing

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

in that component's helper's close function

component.find("overlayLib").notifyClose();

Looks like previous answers no longer work. Here is the solution that worked for me. It seems that now you can close this modal only from a returned promise so we can save it and use later:

Add an attribute to a component with an overlay library

<aura:attribute name="modalPromise" type="Aura.Action"/>

Then save the returned promise to that attribute

var modalPromise = component.find('yourOverlayLibId').showCustomModal({ ... });
component.set("v.modalPromise", modalPromise);

And when you need to close your modal you can use the previously saved promise

component.get('v.modalPromise').then(
    function (modal) {
        modal.close();
    }
);

That's it. Don't forget that all that stuff is happening in the component containing <lightning:overlayLibrary> tag. So from the actual modal, you'll probably have to fire an event to trigger this flow.


Add the OverlayPanel to an attribute of type Aura.Component[] so that it could be reached from the JS controller.

Component

<aura:component>
    <aura:attribute name="overlayPanel" type="Aura.Component[] />
    <lightning:overlayLibrary aura:id="overlayLib"/>
    // body of component
</aura:component>

Controller

({
  showModal : function(cmp, evt, helper) {
    component.find('overlayLib').showCustomModal({
      //modal attributes
    }).then(function (overlay) {
      component.set('v.overlayPanel', overlay);
    });
  },
  handleOk : function(cmp, evt, helper {
    var overlayPanel = component.get('v.overlayPanel');
    overlayPanel[0].close();
  }
})