1

I have this scenario. I am having a getRecord wire method in parent component which is assigning a field value to the variable. That value is passed to the child component. I have a connectedCallback() function in the child component which is having some logic based on the value passed through the parent component.

Issue: The wire method in parent component is running after the connected callback() function in the child component and getting the value as undefined even though the record has value on that field. Can anyone help in resolving this.

Parent Component: JS

import STATUS_FIELD from @salesforce/schema/customObject__c.status__c;
import { getRecord } from 'lightning/uiRecordApi'

const FIELDS = [STATUS_FIELD];

@api recId
@track status;
@track error;

@wire(getRecord, {recordId: '$recId', fields: FIELDS}) details({error,data}) {
if(data) {
this.status = data.fields.status__c.value;
} else {
this.error = error;
}
}

HTML (calling child component)

<template >
<child-component status-value={status} >
</child-component>
</template>

CHILD Component

JS

@api statusValue;

connectedCallback() {

if(this.statusValue == 'Finished'){
//some logic
}
}
//statusValue is coming as undefined here but the value is actually Finished.
2

Make the following changes in parent component and it will start working.

Parent Component: JS

import STATUS_FIELD from @salesforce/schema/customObject__c.status__c;
import { getRecord } from 'lightning/uiRecordApi'

const FIELDS = [STATUS_FIELD];

@api recId
@track status;
@track error;
@track flagIndicatingDataHasBeenLoadedInVariables = false;

@wire(getRecord, {recordId: '$recId', fields: FIELDS}) details({error,data}) {
if(data) {
this.status = data.fields.status__c.value;
this.flagIndicatingDataHasBeenLoadedInVariables = true;
} else {
this.error = error;
}
}

HTML (calling child component)

<template if:true={flagIndicatingDataHasBeenLoadedInVariables}>
     <child-component status-value={status} >
     </child-component>
</template>

Explanation: We are setting a flag after the data is loaded. Only after data is loaded in the parent, it will be passed to the child component.

| improve this answer | |
3

Here parent component is passing account-name prop to child. You don't need connectedCallback() in child for the custom logic, rather you need renderedCallback(). More detailed documentation here

child.html

<template>
    <p>Helllo this is child</p>
    <p>{accountName}</p>    
</template>

child.js

import { LightningElement, api } from 'lwc';

export default class ChildComponent extends LightningElement {
    @api accountName;
    renderedCallback() {
        console.log('Hello this is in render');
        console.log(this.accountName);
        **add you conditional business logic here**
    }
}

parent.html

<template>
<lightning-card title="My Account Record" icon-name="standard:account">
    <template if:true={account.data}>
        <c-child-component account-name={name}>
        </c-child-component>
    </template>
    <template if:true={account.error}>
        {account.error}
    </template>
</lightning-card>

parent.js

import { LightningElement, wire, api } from 'lwc';
import {getRecord} from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Account.Name';

export default class TestSO extends LightningElement {
    @api recordId;
    @wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD] })
    account;

    get name() {
        return this.account.data.fields.Name.value;
    }
}
| improve this answer | |
  • 1
    When including logic in the renderedCallback function, you should create a variable to store when it runs, otherwise it will execute every time the component re-renders. A simple if (this.initialized) and this.initialized=true will do. – stackasaur Jul 24 at 19:09

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.