I have a modal with a footer. The footer is just for Cancel and Save buttons, and their respective JS functions.

Modal Markup

<lightning:overlayLibrary aura:id="overlayLib"/>
<lightning:button name="modal" label="Create Pet" onclick="{!c.handleShowModal}"/>

JS Which Opens the Modal

handleShowModal : function (component, event, helper) {
    var modalBody;
    var modalFooter;
        ["c:IFBPetCreate", {"record": component.get("v.newPet"), 
                            "needsOwner": component.get("v.missingPetOwner"), 
                            "isEU": component.get("v.isEuUser"), 
                            "contList": component.get("v.contList"), 
                            "isLead": component.get("v.isLead")}],

        ["c:ModalFooter", {"recordId": component.get("v.recordId"),
                           "newPet": component.get("v.newPet")}]
    function(components, status){
        if (status === "SUCCESS") {
            modalBody = components[0];
            modalFooter = components[1];
               header: "New Pet",
               body: modalBody, 
               footer: modalFooter,
               showCloseButton: false,
               cssClass: "my-modal,my-custom-class,my-other-class",
               closeCallback: function() {
                 //alert('You closed the alert!');

Footer Component Markup

<aura:component implements="force:hasRecordId" controller="CasePetList_Controller">

    <aura:attribute name="recordId" type="String" />
    <aura:attribute name="newPet" type="Pet__c" default="{'sobjectType':'Pet__c', 'Active__c':true}" />

    <lightning:overlayLibrary aura:id="overlayLib"/>
    <lightning:button name="cancel" label="Cancel" onclick="{!c.handleCancel}"/>
    <lightning:button name="save" label="Save" variant="brand" onclick="{!c.handleSave}"/>


Notice that it has an apex controller, because one of its methods is intended to be invoked in the footer's cancel JS.

Footer Cancel JS

handleCancel : function(component, event, helper) {
    console.log('handleCancel: component: '+component);
    var action = component.get("c.setNewPet");  
        console.log('handleCancel: action: '+action);   
            recId: component.get("v.recordId")
        action.setCallback(this, function(response) {
            var state = response.getState();
            if(state === "SUCCESS") {
                component.set("v.newPet", response.getReturnValue());
                console.log('Problem getting new pet, response state: ' + state);

The problem is that I receive this error when I click the cancel button:

enter image description here

It's as if setting an apex controller for a modal-footer component doesn't do anything? Can we not use apex controllers in modal-footer components? That's hard to imagine, so am I missing something?

  • Does your CasePetList_Controller class have a method setNewPet that accepts a Id or string parameter? Make sure its aura enabled! – codeyinthecloud Oct 22 '18 at 17:39
  • It does and it is aura enabled. It works fine in another component. – Gabriel Rivera Oct 22 '18 at 18:28
  • What does your console.log('handleCancel: action: '+action); print? – Jayant Das Oct 22 '18 at 18:50
  • Try executing the noficyClose() method in apex call's callback? – Raul Oct 22 '18 at 20:08
  • @JayantDas "handleCancel: action: undefined." By comparison, in the component where it works: "handlePetModalCancel: action: SecureAction: [object Object]{ key: {"namespace":"c"} }" – Gabriel Rivera Oct 22 '18 at 20:16

As for your question:

Can we not use apex controllers in modal-footer components?

You can use apex controllers from any component.

Based on my quick replication of your issue, your issue is on this line in the handleCancel JS controller method, where you are closing the overlay right before performing any action.

handleCancel : function(component, event, helper) {

Because you have already closed the modal, thus you are not able to perform any further action in the JS.

You need to close your modal only when you action has completed. Because if you do it outside of your callback's success, the action will be only en-queued and will execute asynchronously. To be able to do so, remove the first line from your JS controller and handle it in the callback's success block. Something as below, and that should work.

handleCancel : function(component, event, helper) {
    // remove closing of modal from here and put in success
    console.log('handleCancel: component: '+component);

        if(state === "SUCCESS") {
            component.set("v.newPet", response.getReturnValue());
            component.find("overlayLib").notifyClose(); // close only when success
  • 1
    Excellent! Great lesson learned. – Gabriel Rivera Oct 22 '18 at 20:20
  • Likewise :). Very easy to skip this, but with some hit and try, figured out what was happening instead. – Jayant Das Oct 22 '18 at 20:21

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.