Posted on

@api decorator and Passing data down the hierarchy in Lightning Web Component.

As we discussed in the last blog, the Lightning Web Components programming model has three decorators that add functionality to property or function.

  1. @track
  2. @api and
  3. @wire

In this blog, will learn about @api decorator and how it is useful in passing data down the component hierarchy in Lightning Web Component.

@api decorator: When you want to make the property reactive and accessible outside of the component then declared the property of a component by @api decorator. We can define @api decorator as public property or as a public method.

  1. @api decorator as a public property:

To expose a public property, decorate the field with @api on the child component. Public properties define the API for a component.

If the value of reactive property changes, the child component’s template re-renders any content that references the property. The parent component or owner component can set values to the public properties which we will discuss later in this blog.

Example: Import the @api decorator from LWC and define the field with @api followed by field name. This code exposes the “fruitName" field as a public property.

<!– childComponent.js–>

import { LightningElement, api } from 'lwc';
export default class ChildComponent extends LightningElement {
    @api fruitName = 'Apple';
}

2. @api decorator as a public method:

To expose a public method, decorate the method with @api on the child component. Public methods are part of a component’s API. To communicate down the containment hierarchy, owner or parent components can call JavaScript methods on child components which we will discuss later in this blog.

Example: Import the @api decorator from LWC and define the method with @api followed by method name. This code exposes the method “assignNewFruitName” as a public property.

<!– childComponent.js–>

import { LightningElement, api } from 'lwc';
export default class ChildComponent extends LightningElement {
    fruitName;

    @api 
    assignNewFruitName(){
      this.fruitName ='Apple';
    }

Passing data down the component hierarchy

Now, we have discussed, how to expose a property or a method as public reactive property or a method.

The main aim to define the public property or a public method is to communicate between the components and in our case to communicate down the component hierarchy (from a parent component to a child component)

There are three ways to pass data from a parent to a child component.

  1. As a public property
  2. As a public getter and setter
  3. As a public method

Public Properties:

Public property is the simplest way to communicate down the hierarchy. As discussed above, decorate the child component field with @api decorator. This allows the parent component to set the child component property.

A Parent component can assign a value to the property of a child component in two different ways.

(i) Via a custom HTML attribute

(ii) Dynamically with JavaScript

Let’s see this with the help of examples.

<!–childComponent.js–>

@api fruitName;

1. In this, we are setting the child component’s field fruitName via a parentComponent‘s HTML attribute.

<!–parentComponent–>

<!--.html-->

<template>
   <c-child-component fruit-name={fruitName}></c-child-component>
</template>


<!--.js-->

this.fruitName='Apple';

2: In this, we are setting the child component’s field fruitName dynamically with parentComponent‘s JavaScript.

<!–parentComponent–>

<!--.html-->

<template>
   <c-child-component></c-child-component>
</template>

<!--.js-->

this.template.querySelector("c-child-component").fruitName='Apple';

Note: Whenever any public property is updated by the owner or parent component, the child component re-renders. Using public properties you cannot run custom logic on the child component when the value changes and the child component should not assign values to its public properties.

Public getters and setters:

If you want to execute logic each time a public property is set, write a custom setter.

Public getters and setters behave the same way as public properties when used in the parent component. However, they allow the child component to execute custom logic when retrieving or updating a value. Additionally, a child component is able to set values using its own setters.

Annotate either the getter or the setter with @api, but not both. It’s a best practice to annotate the getter.

We can call the child component setter method either via a custom HTML attribute or dynamically with JavaScript given in the below example:

<!–parentComponent–>

via a custom HTML attribute :

<!--.html-->

<template>
   <c-child-component fruit-name={fruitName}></c-child-component>
</template>


<!--.js-->

this.fruitName='Apple';

OR

dynamically with JavaScript :


<!--.html-->

<template>
   <c-child-component></c-child-component>
</template>


<!--.js-->

this.template.querySelector("c-child-component").fruitName='Apple';

<!–childComponent.js–>

import { LightningElement, api } from 'lwc';
export default class ChildComponent extends LightningElement {
    _fruitName;

    @api
    get fruitName() {
        return this._fruitName;
    }

    set fruitName(value) {
       this._fruitName= value;
    }

}

Public methods

Public methods give you the flexibility to perform your own custom logic by passing multiple parameters at once to the child components.

Unlike public properties or setters, public methods can not be exposed in the component’s HTML tag. They can only be called dynamically with JavaScript. This means whenever any public property is updated by the owner or parent component, the child component will not be re-renders in this case. The component only re-renders if the method modifies properties used in the component’s template.

<!–parentComponent–>


<!--.html-->

<template>
   <c-child-component></c-child-component>
</template>


<!--.js-->

this.template.querySelector("c-child-component").customfunction(value1, value2);

<!–childComponent.js–>

@api
customfunction(value1, value2){
    //perform your custom logic here
}

Leave a Reply

Your email address will not be published. Required fields are marked *