1

I'm currently facing a weird issue with Salesforce, and I don't know how to fix it. I have a grey error message showing up each time I test the following code. I can't get my head around it and it's driving me crazy.

I hope that you guys will be able to help me on this.

thanks in advance.

Below the error code and it's followed by the component code (parent and child), and the apex controller.

Uncaught Error in $A.getCallback() [Cannot read property 'getElement' of 
undefined]
throws at https://xxxx--sandboxv1.lightning.force.com/auraFW/javascript/nRhh35vBDuL0P3mlbcWPkg/aura_prod.js:8:15
Object.updateAriaDescribedBy()@https://xxxx--sandboxv1.lightning.force.com/components/lightning/select.js:3:315
Object.updateHelpMessage()@https://xxxx--sandboxv1.lightning.force.com/components/lightning/select.js:4:106
Object.showHelpMessage()@https://xxxx--sandboxv1.lightning.force.com/components/lightning/select.js:7:239
Object.eval()@https://xxxx--sandboxv1.lightning.force.com/components/lightning/select.js:8:60
eval()@https://xxxx--sandboxv1.lightning.force.com/libraries/lightning/eventEmitterLibrary/EventEmitter.js:1:550
b.emit()@https://xxxx--sandboxv1.lightning.force.com/libraries/lightning/eventEmitterLibrary/EventEmitter.js:1:528
a.leave()@https://xxxx--sandboxv1.lightning.force.com/libraries/lightning/interactingStateLibrary/InteractingState.js:2:134
eval()@https://xxxx--sandboxv1.lightning.force.com/libraries/lightning/rateLimitLibrary/debounce.js:1:349

this below is the code for the parent lightning component (cmp code)

<aura:component controller="createOrderFromWonOpprotunityController" implements="force:lightningQuickActionWithoutHeader,flexipage:availableForRecordHome,force:hasRecordId,force:hasSObjectName" access="global">  
<aura:attribute name="isWon" type="Boolean" default="false"/>
<aura:attribute name="shouldContinue" type="Boolean" default="false"/>
<aura:attribute name="notified" type="String" />

<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

<div class="slds-scope">
    <div id="notificationRes"><span style="color: red;">{!v.notified}</span><br/></div>

    recordId = {!v.recordId}
    shouldContinue = {!v.shouldContinue}

    <aura:if isTrue="{!v.isWon == false}">
        <p> Your current opportunity is not <strong>closed</strong>. Please select on of the status below.</p>
        <lightning:select aura:id="selectClosedStage" name="selectClosedStage" label="Select an Stage Status" onchange="{!c.changeStatus}">
            <option value="">choose one...</option>
            <option value="Closed Won">Closed Won</option>
            <option value="Closed Lost">Closed Lost</option>
        </lightning:select>
        <aura:set attribute="else">
            <c:createOrderFromWonOpportunityAfterClosedWon recordId="{!v.recordId}" shouldContinue="{!v.shouldContinue}"/>
        </aura:set>
    </aura:if>
</div>    

here is the js controller

({
doInit : function(component, event, helper) {
    var action = component.get("c.isClosedWon");
    action.setParams({
        "oppId" : component.get("v.recordId")
    });
    action.setCallback(this, function(response) {
        var state = response.getState();
        console.log("doInit >> val >> " + response.getReturnValue());
        console.log("doInit >> state >> " + state);
        if (state === "SUCCESS") {
            component.set("v.isWon", response.getReturnValue());
            if (response.getReturnValue()) 
                component.set("v.shouldContinue", true);
            else 
                component.set("v.shouldContinue", false);
        } else {
            component.set("v.notified", "A server Error occuried, please try again later.");
        }
    });
    $A.enqueueAction(action);
},

changeStatus : function (component, event, helper) {
    try {
        var selectValue = component.find("selectClosedStage").get("v.value");
        var action = component.get("c.CustomUpdateRecord");
        action.setParams({
            "oppId" : component.get("v.recordId"),
            "stageName" : selectValue
        });
        console.log('changeStatus >> selectValue >> '+ selectValue);
        action.setCallback(this, function(response) {
            var res = response.getReturnValue();
            console.log("changeStatus >> val >> " + response.getReturnValue());
            console.log("changeStatus >> state >> " + response.getState());
            if (selectValue === 'Closed Won') {
                component.set("v.isWon", true);
                component.set("v.shouldContinue", true);
            } else {
                component.set("v.isWon", false);
                component.set("v.shouldContinue", false);
                component.set("v.notified", 'the current opportunity is Closed Lost. No Order can be created for it');
            }
        });
        $A.enqueueAction(action);
    } catch (e) {
        console.log(e);
    } 
}
})

Here is the child component:

<aura:component controller="createOrderFromWonOpprotunityController">
<aura:attribute name="recordId" type="String"/>
<aura:attribute name="shouldContinue" type="Boolean"/>
<aura:attribute name="errorCheck" type="List" />
<pre>
     under child : 
     recordId = {!v.recordId}
     shouldContinue = {!v.shouldContinue}
</pre>
<aura:if isTrue="{!v.shouldContinue}">
   <div class="slds-grid slds-grid--align-spread">
       You are about to convert the current Opportunity to an Order.<br/>
       If you are ready, Please click on "Confirm" button below<br/>
       <lightning:button label="Confirm" onclick="{!c.doSubmit}" class="slds-m-top--medium" />
   </div>
   <aura:set attribute="else">
       <p>Sorry you can not convert the current Opportunity to an Order for the following reason.</p>
       <aura:iteration items="{!v.errorCheck}" var="item">
           <span style="color: red;"> - {!item}</span>
       </aura:iteration>
   </aura:set>
</aura:if>
</aura:component>

and here is the js child component:

({
 doSubmit : function (component, event, helper) {
    console.log("confirm has been hit");
    var action = component.get("c.createOrder");
    action.setParams({
         "oppId" : component.get("v.recordId")
    });
    console.log("cdoSubmit >> " + component.get("v.recordId"));
    action.setCallback(this, function(response) {
        var res = response.getReturnValue();
        console.log("res >> " + res);
        if (response.getState() === 'SUCCESS') {
            var NotificationError = [];
            if (res !== 'SUCCESS' && res !== '') {
                switch(res) {
                    case 'NotClosedWon':
                        NotificationError.push("change this Opportunity Status as Won before continuing.");
                        break;
                    case 'NoProduct' :
                        NotificationError.push("The current Opportunity does not have any associated products");
                        break;
                    case 'ErrorAccountBillingCity' :
                        NotificationError.push("The Account associated to the current Opportunity is missing the Billing City Information.");
                        break;
                    case 'ErrorAccountBillingStreet' :
                        NotificationError.push("The Account associated to the current Opportunity is missing the Billing Street Information.");
                        break;
                    case 'ErrorAccountBillingState' :
                        NotificationError.push("The Account associated to the current Opportunity is missing the Billing State Information.");
                        break;
                    case 'ErrorAccountBillingPostalCode' :
                        NotificationError.push("The Account associated to the current Opportunity is missing the Billing Postal Code Information.");
                        break;
                    case 'ErrorAccountBillingCountry' :
                        NotificationError.push("The Account associated to the current Opportunity is missing the Billing Country Information.");
                        break;
                    case 'ErrorNoContactAssociated' :
                        NotificationError.push("The Account associated to the current Opportunity do not have any Contact associated.");
                        break;
                    case 'Error' : 
                        component.set("v.notified", "An Error happened, please try again. If it persists please contact your administrator");
                        break;
                } //end switch
                component.set("v.errorCheck", NotificationError);
                component.set("v.shouldContinue", false);        
                console.log(NotificationError);
            } //end if
            else {
                console.log("after Process: " + res);
                var resultsToast = $A.get("e.force:showToast");
                resultsToast.setParams({
                    "title": "Conversion done succesfully",
                    "message": "Your Order is now available under the Order tab. Please review and Activate." 
                });
                $A.get("e.force:closeQuickAction").fire();
                resultsToast.fire();
            }
        } else {
                component.set("v.errorCheck", ["An Error happened, please try again. If it persists please contact your administrator"]);
        }
    });
     $A.enqueueAction(action);
}
})

and finally the apex controller for it:

public with sharing class createOrderFromWonOpprotunityController {

@AuraEnabled
public static Boolean isClosedWon (String oppId) {
    try {
        Opportunity opp = [SELECT Id, IsClosed, StageName FROM Opportunity Where Id= :oppId][0];
        if( opp.StageName.equals('Closed Won'))
         return true;
        else return false;
    } catch(Exception e) {
        system.debug(e);
    }
    return false;
}


@AuraEnabled
public static Boolean CustomUpdateRecord (String oppId, String stageName) {
    try {
        Opportunity opp = [SELECT Id, IsClosed, StageName FROM Opportunity Where Id= :oppId][0];
        opp.StageName = stageName;
        update opp;
        return true;
    } catch(Exception e) {
        system.debug(e);
    }
    return false;
}

public static String isMissingData(String oppId) {
    try {
        Opportunity opp = [SELECT Id, AccountId, IsClosed, StageName, CloseDate, OrderId__c FROM Opportunity Where Id= :oppId][0];
        system.debug(opp);
        Boolean shouldContinue = opp.IsClosed && opp.StageName == 'Closed Won'; //&& (opp.OrderId__c == null || opp.OrderId__c == '');
        system.debug('shouldContinue >>> ' + shouldContinue);
        if (shouldContinue) {
            if (isMissingOpportunityProduct(oppId))
                return 'NoProduct';
            else { 
                String missingInfoAccount = isMissingAccountInfo(opp);
                if (!missingInfoAccount.equals(''))
                    return missingInfoAccount;
                String oppSED = isMissingOpportunityProductStartEndDate(oppId);
                if (!oppSED.equals(''))
                    return oppSED;
                /*
                    String missingIntakeForm = MissingIntakeForm(oppId);
                    if (!missingIntakeForm.equals(''))
                        return missingIntakeForm;
                */
            }
        } else {
            return 'NotClosedWon';
        }
        return 'SUCCESS';
    }catch(Exception e) {
        system.debug(e);
        return 'Error';
    }
}

public static String isMissingAccountInfo(Opportunity opp) {
    Account acc     = [SELECT Id, AccountNumber, BillingStreet, BillingCity, BillingPostalCode, BillingState, BillingCountry FROM Account WHERE Id = :opp.AccountId][0];
    system.debug(acc);
    Contact contact = [SELECT Id FROM Contact WHERE AccountId = :acc.Id][0];
    if (acc.BillingCity == null)
        return 'ErrorAccountBillingCity';
    if (acc.BillingStreet == null)
        return 'ErrorAccountBillingStreet';
    if (acc.BillingPostalCode == null)
        return 'ErrorAccountBillingPostalCode';
    if (acc.BillingState == null)
        return 'ErrorAccountBillingState';
    if (acc.BillingCountry == null)
       return 'ErrorAccountBillingCountry';
    if (contact == null)
        return 'ErrorNoContactAssociated';
    return '';
}

public static Boolean isMissingOpportunityProduct(String oppId) {
    try {
        List<OpportunityLineItem> ProductsInOpportunity = [SELECT Id FROM OpportunityLineItem WHERE OpportunityId = :oppId];
        return ProductsInOpportunity.size() == 0;
    } catch(Exception e) {
        system.debug(e);
        return true;
    }
}

public static String isMissingOpportunityProductStartEndDate(String oppId) {
    List<OpportunityLineItem> ProductsInOpportunity = [SELECT Id, Product2Id, ServiceDate, End_Date__c FROM OpportunityLineItem WHERE OpportunityId = :oppId];
    if (ProductsInOpportunity.size() > 0) {
        for(OpportunityLineItem line : ProductsInOpportunity) {
            if (line.ServiceDate == null || line.End_Date__c == null)
                return 'MissingDate';
        }       
    }
    return '';
}

public static String isMissingIntakeForm(String oppId) {
    try {
        List<OpportunityLineItem> ProductsInOpportunity = [SELECT Id, Name, OpportunityId, Intake_Form_Required__c,
                                                                  IntakeFormId__c, Product2Id, Product_Intake_Form__c
                                                           FROM OpportunityLineItem
                                                           WHERE OpportunityId = :oppId];
        system.debug('ProductsInOpportunity');
        system.debug(ProductsInOpportunity);
        for (OpportunityLineItem item : ProductsInOpportunity) {
            if (item.Intake_Form_Required__c == true ) {
                Product2 pro = [SELECT Id, Name, Product_Intake_Form__c FROM Product2 WHERE Id = : item.Product2Id][0];
                String objIntakeFormName = pro.Product_Intake_Form__c;
                String query = 'SELECT Id FROM ' + objIntakeFormName + ' WHERE OpportunityProductId__c = \''+ item.Id +'\'';
                List<SObject> IntakeForms = Database.query(query);
                if (IntakeForms.size() == 0)
                    return 'missingIntakeForm#'+ pro.Name;
                else {
                    if (item.Product_Intake_Form__c == '' || item.Product_Intake_Form__c == null)
                        item.Product_Intake_Form__c = objIntakeFormName;
                    item.IntakeFormId__c = IntakeForms[0].Id;
                    update item;
                }
            }
        }
        return '';
    }
    catch(Exception e) {
       system.debug(e);
        return 'missingIntakeForm#Error';
    }
}


@AuraEnabled
public static String createOrder(String oppId) {
    try {
        //if (updateOppAsWon)
        //    createOrderFromWonOpprotunityController.CustomUpdateRecord(oppId);
        system.debug('createOrder');
        String res = createOrderFromWonOpprotunityController.isMissingData(oppId);
        if (!res.equals('SUCCESS'))
            return res;
        Opportunity opp =  [SELECT Id,IsClosed, Name, AccountId,  Amount, CloseDate,  Description, HasOpportunityLineItem,
                OwnerId, Pricebook2Id, StageName, OrderId__c
                FROM Opportunity 
                WHERE Id = :oppId][0];
        system.debug(opp);
        List<OpportunityLineItem> ProductsInOpportunity = [SELECT Id, Name, Name__c, Description, OpportunityId, Product2Id, PricebookEntryId, ProductCode, UnitPrice, 
                                                            ListPrice, Final_Price__c, Months__c, SetupFee__c, ServiceDate, End_Date__c, Booking_Date__c,
                                                            Product_Intake_Form__c, IntakeFormId__c
                                                           FROM OpportunityLineItem 
                                                           WHERE OpportunityId = :oppId];
        Account acc  = [SELECT Id, AccountNumber, BillingStreet, BillingCity, BillingPostalCode, BillingState, BillingCountry FROM Account WHERE Id = :opp.AccountId][0];
        if (opp.HasOpportunityLineItem) {
            system.debug(ProductsInOpportunity);
            system.debug(acc);
            Order order         = new Order();
            order.AccountId     = acc.Id;
            order.BillToContactId    = [SELECT Id FROM Contact WHERE AccountId = :acc.Id][0].Id;
            order.BillingStreet      = acc.BillingStreet;
            order.BillingCity        = acc.BillingCity;
            order.BillingPostalCode  = acc.BillingPostalCode;
            order.BillingState       = acc.BillingState;
            order.BillingCountry     = acc.BillingCountry;
            order.OpportunityId      = opp.Id;
            order.Pricebook2Id       = opp.Pricebook2Id;
            order.Name               = 'Order_' + opp.Name;
            order.OwnerId            = opp.OwnerId;
            order.EffectiveDate      = system.today();
            order.Status             = 'Draft'; // is status set to Activate, it cannot be changed
            insert order;
            system.debug(order);
            List<OrderItem> orderItems = new List<OrderItem>();
            for (OpportunityLineItem oppItem : ProductsInOpportunity) {
                Product2 pro = [SELECT Id, Name, ProductCode FROM  Product2 WHERE Id = : oppItem.Product2Id][0];
                OrderItem orderProduct = new OrderItem();
                orderProduct.OrderId          = order.Id;
                orderProduct.Name__c          = oppItem.Name__c;
                orderProduct.Status__c        = 'Draft';
                orderProduct.Product2Id       = pro.Id;
                orderProduct.Product_Name__c  = pro.Name;
                orderProduct.PricebookEntryId = oppItem.PricebookEntryId;
                orderProduct.Description      = oppItem.Description;
                orderProduct.Quantity         = oppItem.Months__c;
                orderProduct.Month__c         = oppItem.Months__c;
                orderProduct.UnitPrice        = oppItem.UnitPrice;
                orderProduct.ServiceDate      = oppItem.ServiceDate; // correspond to start date
                orderProduct.EndDate          = oppItem.End_Date__c;
                orderProduct.Booking_Date__c  = oppItem.Booking_Date__c;
                orderItems.add(orderProduct);
            }
            insert orderItems;
            opp.OrderId__c = order.Id;
            update opp;
            system.debug(opp);
            return 'SUCCESS'; //order.Id;
       }
    } catch( Exception e) {
        system.debug(e);
        return 'Error';
    }
    return '';

}
}
  • Error is with child component or parent component? You can try removing the child component and check for it, it'll make troubleshooting fast and specific. – Sikha Baid Oct 24 '17 at 17:32
  • I don't know. the code is working when I close the grey salesforce dialog box. – Yassir Abdullah Oct 24 '17 at 17:34
  • so I removed the child component from the parent, and I still have the same error. – Yassir Abdullah Oct 24 '17 at 18:04
  • and I now the parent is working because the record is updated as expected. – Yassir Abdullah Oct 24 '17 at 18:05
  • 1
    Hi guys, the code is in sandbox, I have a custom action creating for me the order from an Won Opportunity. So both parent and child are working as expected. The parent is passing the RecordId to the child as expected and the child component is creating the order record as expected and updating the initial opportunity record as well. Code/execution wise, everything is working fine as expected. The only problem is (I assume) when the child is initialize from the parent I have that weird problem of a Salesforce grey error box showing up. – Yassir Abdullah Oct 25 '17 at 11:53
1

so I discovered the issue : It'on the parent component, instead of using a select I switch over to a radio button.

Per my understanding, the onchange listener on the select was triggering the framework error. I don't exactly know why it's doing it, but I presume that after the attribute was set, the select might be rerender and such as cause the listener to be fired again with an empty value.

so I change the select in the parent component to :

<div class="slds-form-element__control">
    <div class="slds-radio_button-group">
        <span class="slds-button slds-radio_button">
             <input type="radio" id="first" name="selectClosedStage" data-value="Closed Won" value="Closed Won" onclick="{!c.changeStatus}" />
             <label class="slds-radio_button__label" for="first">
                   <span class="slds-radio_faux">Closed Won</span>
             </label>
         </span>
         <span class="slds-button slds-radio_button">
              <input type="radio" id="second" name="selectClosedStage" data-value="Closed Lost" value="Closed Lost" onclick="{!c.changeStatus}" />
              <label class="slds-radio_button__label" for="second">
                   <span class="slds-radio_faux">Closed Lost</span>
              </label>
         </span>
    </div>

and also in the js controller, to catch the value related to the onclick I'm doing :

 var selectValue = event.currentTarget.dataset.value; 

Thanks everyone for the help.

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.