4

I am having problem in dynamically getting the value in my child Lightning Web Component I have a Parent Component and Child Component. I am passing the @api value as follows :

Parent.html

<lightning-input type="checkbox" label="isFieldChecked" value={isfieldchecked} onchange={handleValueChange}>
 <c-child 
    isvaluechecked={isfieldchecked}
 ></c-child>
</lightning-input>

Parent.js

isfieldchecked = false;

handleValueChange(event) {
   this.isfieldchecked = event.target.checked; //value onchange is not getting reflected in child component
}

child.html

<lightning-input type="checkbox" label="isChecked" value={isfieldchecked} onchange={handlecheckboxchanged}></lightning-input>

child.js

@api isvaluechecked;
connectedCallback() {
   console.log('isValueChanged::' + this.isvaluechecked);
}
    handlecheckboxchanged() {
        if(this.isvaluechecked) { 
console.log('isValueChanged::' + this.isvaluechecked); //cannot see the value updated when updated on parent
    //perform some operations
        }
    }

In the above scenario, when I check/uncheck the checkbox in the parent component, I dont see it changed in the child component where I am invoking the onchange method.

0

2 Answers 2

2

With the great help of @sfdcfox & @Phil W comments on the answer provided by @sfdcfox, here I have summarised an answer.

Key learning points:

  1. onchange event on child is only triggered if you are clicking the checkbox of the child component. Although you are passing in the value from the parent, the value change in parent does not trigger the onchange handler function in the child.

To work with this, what you can do is using a getter/setter and call/perform your onchange method in the setter, because the setter will run each time there's a new value being passed.

Child.Js

_isvaluechecked;
@api 
set isvaluechecked(val){
    console.log('hi'); // just to check to see if setter is called.
    this._isvaluechecked = val;
    this.handlecheckboxchanged();
}

get isvaluechecked(){
    return this._isvaluechecked;
}

handlecheckboxchanged() {
    if(this.isvaluechecked) { 
        console.log('isValueChanged::' + this.isvaluechecked);
    }
}

Once again, I would like to thank @sfdcfox and @Phil W, for their help. As these really helped me gained a good understanding as well! :)
Credits: @sfdcfox and @Phil W.

2
  • Why do we need _isvaluechecked ? Jul 20, 2023 at 18:55
  • 1
    It’s just a variable, to aid the usage of getter/setter. When you receive a value from the setter, where would you save the value? So we create a new variable and save is there. Since this new variable holds the value, that is passed in; in the getter method we return this value. Of course you can name the variable to whatever you want, such as #value also. So when the parent pass in the isvaluechecked value, setter method is called, we assign the value to _isvaluechecked. Then in the child component wherever isvaluechecked variable is used, the getter method will be called to return the value
    – prem22
    Jul 21, 2023 at 2:17
4

@api makes a property read-only. The parent component must not use @api for a property it intends to change.

@api isfieldchecked = false;

should be:

isfieldchecked = false;
17
  • I tried with this as well and it did not work so I went ahead and changed it to @api since it is publicly available. Jul 20, 2023 at 16:30
  • This answer is incomplete if you consider output properties for use in flows. These must be @api setter/getter properties, allowing the property to be updated by the component it belongs to so that the update can then be communicated back to the flow.
    – Phil W
    Jul 20, 2023 at 16:31
  • 2
    @SFDCLearner Note that a checkbox uses the checked property--if you're expecting the child checkbox to check, use <lightning-input checked={isvaluechecked} ...
    – sfdcfox
    Jul 20, 2023 at 16:45
  • 1
    @SFDCLearner Correct. connectedCallback is only called when the component first connects to the DOM, and onchange won't be called unless the user manually clicks the child checkbox. If you want to see changes to the property, the appropriate ways would be either a renderedCallback or a getter/setter pair. Try this in the child: #value; @api set isvaluechecked(value) { console.log(value); this.#value = value; } get isvaluechecked() { return this.#value; } instead of @api isvaluechecked = false.
    – sfdcfox
    Jul 20, 2023 at 17:02
  • 1
    @prem22 The public properties themselves have been unprotected for a couple of years now. However, developers should treat them as readonly. Data binding can only occur from parent to child, and if the parent changes a bound value, the child will lose whatever data they assumed they had. This can make debugging more difficult than it needs to be, especially in large projects.
    – sfdcfox
    Jul 20, 2023 at 18:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .