LWC How to Get Parent Value

child-to-parentjavascriptlightning-web-components

How do you get the parent value? I am trying to get Order_Bill_To__r.Comm_Model__c without using APEX. I thought I could do this using __r however when I run this it says that [LWC component's @wire target property or method threw an error during value provisioning. Original error:
[Cannot read property 'value' of undefined]]

It is failing specifically on this line with the above error
this.Order_Bill_To__r.Comm_Model__c = this.quote.fields.Order_Bill_To__r.Comm_Model__c.value

    import { LightningElement, api, wire, track } from 'lwc';
    import { getObjectInfo } from 'lightning/uiObjectInfoApi';
    import QUOTE_OBJECT from '@salesforce/schema/SBQQ__Quote__c';
    import SubmitQuoteForApproval from '@salesforce/apex/clsSubmitObjectForApproval.SubmitForApproval';
    const FIELDS = ['SBQQ__Quote__c.Order_Bill_To__r.Comm_Model__c', 'SBQQ__Quote__c.RecordTypeId', 'SBQQ__Quote__c.SBQQ__LineItemCount__c'];
    import { getRecord } from 'lightning/uiRecordApi';
    import { ShowToastEvent } from 'lightning/platformShowToastEvent';
    import { CloseActionScreenEvent } from 'lightning/actions';
    import { getRecordNotifyChange } from 'lightning/uiRecordApi';
    import { updateRecord } from 'lightning/uiRecordApi';
    import ID_FIELD from '@salesforce/schema/SBQQ__Quote__c.Id';

    export default class LwcSubmitQuoteToOrder extends LightningElement {

        @api recordId;
        @api objectApiName;
        @track quote;
        @track ValidationMessage;
        @track recordType;
        @track objectInfo;


        @wire(getObjectInfo,  { objectApiName: QUOTE_OBJECT })
        ObjectInfo;
      
        @wire(getRecord, { recordId: '$recordId', fields: FIELDS })
        wiredRecord({error, data }) {
            if(data) {
                this.quote = data;
                this.SBQQ__LineItemCount__c = this.quote.fields.SBQQ__LineItemCount__c.value;
                this.recordType = this.quote.fields.RecordTypeId.value;
                this.Order_Bill_To__r.Comm_Model__c = this.quote.fields.Order_Bill_To__r.Comm_Model__c.value;
                
                //Must declare that ValidationMessage be nothing. 
                this.ValidationMessage  = '';


                if(this.GetRecordTypeValue() == true){
                    this.UpdateQuote();
                }
                if(this.Order_Bill_To__r.Comm_Model__c == true){
                    this.ValidationMessage = this.ValidationMessage +  'You are submitting an order for an NSO that uses the commissioner model. ‘Transfer Price (USD)’ from the attached Ametek PO is required for all line items.\n'; 
                 }
                
            } 

        async invokeApexMethods() {
                // Update the record via Apex.
                await SubmitQuoteForApproval({idObject: this.recordId})
                // Notify LDS that you've changed the record outside its mechanisms.
                getRecordNotifyChange([{recordId: this.recordId}]);
        }
      
        closeAction(){
           this.dispatchEvent(new CloseActionScreenEvent());
        }
          
        showErrorToast(x) {
            const evt = new ShowToastEvent({
                title: 'Submit Quote For Approval',
                message: x,
                variant: 'Quote has Successfully Submitted',
                mode: 'dismissable'
            });
            this.dispatchEvent(evt);
        } 

         GetRecordTypeValue() {
            // Returns a map of record type Ids 
            const rtis = this.ObjectInfo.data.recordTypeInfos;
            const rtInfo= Object.keys(rtis).find(rti => rtis[rti].name == 'Official_Sales_Quote');
            
            if(this.RecordType===rtInfo){
                return true;
            } else{
                return false;
            }  
            
        }

        UpdateQuote(){
            const fields = {};
            fields[ID_FIELD.fieldApiName] = this.recordId;
            fields[SALESORDER_FIELD.fieldApiName] = true;
            
            const recordInput = { fields };
            updateRecord(recordInput);
        }

    }

Best Answer

Considering that you have deeply nested properties when assigning values, you might want to ensure that they are not returning undefined.

to ensure that the properties in this.quote.fields.Order_Bill_To__r.Comm_Model__c.value populated.

I would suggest you use a combination of Nullish coalescing operator (??) and use Optional chaining (?.)

Ex:

this.quote?.fields?.Order_Bill_To__r?.Comm_Model__c?.value ?? 'default value to avoid undefined'

you can also add type checking, however, given the amount of properties, you'd end up having multiple if statements which can be avoided.

Related Topic