Lightning Web Components: Communicating from Parent to Child Component in LWC

In this post we will discuss about communication between components from parent to child. For example,if on certain events in parent component, I want to pass parameter
to child component or I want to execute certain logic in child component then how will I achieve it.

Passing the property values from parent to child component

Suppose I have two components, a parent component say “testParent” and a child component say “testChild” .

In the child component, We will declare a property with @API decorator say “myName”. This means, the property can be accessed outside of this component now in the parent component. We will set default value of this property say “Salesfore Predator”.

We will pass the value to this child components property from parent ,while declaring the child component inside the parent component.

testChild.html

<template>
    <lightning-card  title = "Contact Details" icon-  name="standard:contact">
        <p>{myName}</p>
    </lightning-card>
</template>

testChild.js

import { LightningElement ,api} from 'lwc';

export default class TestChild extends LightningElement {
    @api myName = 'Salesfore Predator';
}

testParent.html

<template>
   
    <c-test-child my-name = {chilparam} </c-test-child>


</template>

Notice the case while writing the child components name inside parent component. It has to be in a kebab case, also the property’s name is to be in a kebab case only.

testParent.js

import { LightningElement,track } from 'lwc';

export default class TestParent extends LightningElement {

    @track chilparam = 'Knowledge Predator';
        }

Now if you include the testParent inside an Aura App and preview the application, you will see that value passed from parent is displayed instead as it has overridden the child components value.

Calling Child component’s method from Parent

Suppose on click of certain event, say on click of button, We want to change the value passed to the child component in above example.

So, We will make changes to above components.

In child component we will add a method say “testChildMethod” which will recieve paramter also from parent component. Remember this method has to be public ie annoted by @api so that it can be accessed by other components. This method will display alert message and change the value of our “myName” property to “Salesfore Predator” again.

testChild.html

<template>
<lightning-card>
        <lightning-button label="click me" onclick = {handleMe}></lightning-button>
</lightning-card>
</template>

testChild.js

import { LightningElement ,api} from 'lwc';

export default class TestChild extends LightningElement {
    @api myName = 'Salesfore Predator';
    @api testChildMethod(parentParam){
        alert('this is child method'+parentParam.firstname);
        this.myName = 'Salesfore Predator';
    }
}

In parent component , We will add a button , which we will bind to a javascript function and from javascript function we will make call to child components method.

testParent.html

<template>
   
    <c-test-child my-name = {chilparam}> </c-test-child>

    <lightning-button label = 'Call Child Method' onclick={handleCall}></lightning-button>
</template>

testParent.js

import { LightningElement,track } from 'lwc';

export default class TestParent extends LightningElement { handleCall(event){
      var childCompVar  = this.template.querySelector('c-test-child');
      var sendParam = {'firstname': 'Salesforce'};
      childCompVar.testChildMethod(sendParam);
          

    }
}

Notice the syntax while accessing the child component and its method in parent component javascript file.

 this.template.querySelector('div')    - >  This returns the first  div element.
 this.template.querySelectorAll()      - >   This returns array of all div elements in the component

Reload the application. Once you click on ‘Call Child Method’ , alert will pop up which displays the paramter passed from parent component.

Once you close the alert , you wil see the property value will be changed to ‘Salesforce Predator’ again.

So , we will wrap up this post here . Stay tuned for next posts !

Decorators and Properties in Lightning Web Components

Decorators in LWC

There are three majorly use decorators in lightning web components:

  • @api

@api decorators is used to make properties or methods in lightning web component public this way they are accessible outside of the component in which they are declared. For example a parent component can set the value of a property in a child component

  • @track

@track decorator is basically used to make properties or a method
private in lightning web components this property is not accessible outside of lightning that component when in which it is declared

  • @wire

@wire is basically used to read the Salesforce data from apex class into lightning web component. It is generally used while making a server calls to apex class .

Properties in LWC

There are two types of properties in lightning web components:

  • Reactive Properties
    • In case of reactive properties if the value of property changes component gets every rendered

Reactive properties are of two types :

  1. Public reactive properties : Public reactive properties are the one which are declared using @api decorator
  2. Private reactive properties: Private properties are the one which are declared using @track decorators.

  • Non Reactive Properties

Non reactive properties are declared without any decorator ,so even if the value of non reactive property changes component does not get re-render .

However, as per Salesforce Spring ’20 Release Notes , All properties are made reactive proeprties.If property value changes, and the property is used in a template or if a getter of a property that’s used in a template, the component rerenders and displays the new value.

Lets understand all these with the help of exmaples:

We will create two components, one inside another . Let child component be childY and parent be parentY.

childY component

We will create three properties in child component lets say “trackParam”, “apiParam”, “nonReactiveProp” where “trackParam” is private reactive property as it is annoted with @track, “apiParam” is public reactive property as it is annoted with @api and “nonReactiveProp” is non reactive propertiy in javascript file.

Also we have added default values to these properties.Further we have added a button “Test Behaviour” on click of which we will change the value of properties one by one to check the behaviour of component.

childY.html

<template>
<lightning-card title="trackProprtyDemo" icon-name="standard:account">
    Hello {trackParam}
</lightning-card>
<lightning-card title="apiPropDemo" icon-name="standard:account">
    Hello {apiParam}
</lightning-card>
<lightning-card title="nonReactiveDemo" icon-name="standard:account">
    Hello {nonReactiveProp}
</lightning-card>

<div>
    <lightning-button label="Test Behaviour" onclick = {handleparamValues}></lightning-button>
</div>


</template>

childY.js

import { LightningElement,track,api} from 'lwc';

export default class ChildY extends LightningElement {

    @track trackParam = "trackValue";
    @api apiParam = "apiValue";
    nonReactiveProp = "nonReactiveValue";

    handleparamValues(){
       this.trackParam = "value changed for trackParam";
       this.apiParam = "Value changed for APIParam";
       this.nonReactiveProp = "value changed fro non reactive Param";
    }

}

parentY

In the parent component, we are just passing the value to apiParam property of childY component as it is public property.

parentY.html

<template>
    <c-child-y api-param="api Value from Parent" track-param = "track value from parent"></c-child-y>

</template>

parentY.js

import { LightningElement } from 'lwc';

export default class ParentY extends LightningElement {}

Now if you include parent component inside Aura application and load the application you will notice that for “trackParam”and “nonReactiveProp” properties the default values in JS file are displayed and for “apiParam” property , the value passed from parent component is displayed.

Now , If you click on Test Behaviour button, the value of all these properties changes and component gets re-render and new values are displayed.

So , we will wrap up this post here . Stay tuned for next posts !