Mastering @api decorator and Public Properties in LWC

Telegram logo Join our Telegram Channel
@api decorator in LWC

What is Public Property?

Public properties are a crucial aspect of Lightning Web Components (LWC), enabling communication and data exchange between components. They serve as the foundation for a component's API, defining the data it can expose and consume. By declaring a property as public, you make it accessible to other components, allowing them to interact with it.

Consider a scenario where you have a component displaying a product name and its price. To make this information available to other components, you would define public properties for product name and price. Other components could then access these properties to display or manipulate the product information.


The @api Decorator

The @api decorator is a key tool for defining public properties in LWC. It marks a property as public, making it available for consumption by other components. The decorator not only exposes the property but also ensures reactivity, enabling the component to re-render whenever the property's value changes.

Let's see how to use the @api decorator to define a public property. To demonstrate this, let's create a component called ProductCard as below.

JS

import { LightningElement, api } from 'lwc';
export default class ProductCard extends LightningElement {
  @api productName;
  @api price;
}

HTML

<template>
    Product Name: {productName}, <br/>
    Price: {price} INR
</template>

In this example, the @api decorator is applied to the productName and price properties, making them accessible to other components.

Now, let's see how to access public properties of ProductCard from another component (ParentComponent).

<!-- ParentComponent.html -->
<template>
    <!-- calling product card component and setting public prop values -->
    <c-product-card 
        product-name="Smart TV" 
        price="20000">
    </c-product-card>
</template>

Note: Just like the component names the public property names are also converted from camel case to to kebab case. 


@api get and  @api set

The @api decorator can be used with both getters and setters to control property access and modification. The @api get keyword indicates a getter method, allowing other components to retrieve the property's value. Conversely, The @api set signifies a setter method, enabling other components to modify the property's value.

The getter method is called every time the property is accessed and the setter is called every time the property value is set. This allows you to control and modify the property value before it is set or returned.

For instance, you might want to prevent direct modification of the price property, by enforcing a validation rule. By using a setter method, you can control the price update process:

JS

import { LightningElement, api } from 'lwc';

export default class ProductCard extends LightningElement {
  @api
  get price() {
    return this._price;
  }

  @api
  set price(newPrice) {
    if (newPrice < 0) {
      throw new Error('Price cannot be negative');
    }

    this._price = newPrice;
  }

  _price = 0;
}

In this example, the @api get retrieves the value of the private _price property, while the @api set validates and updates that same value. This keeps the actual data hidden from other components and ensures data integrity. 

The leading underscore in _price distinguishes it from the public property while maintaining a clear connection between the two.


@api Functions

In addition to properties, the @api decorator can also be applied to functions, making them part of a component's public API. This allows other components to call these functions, enabling them to interact with the component's internal logic.

For example, you might create a function that updates the product stock:

JS

import { LightningElement, api } from 'lwc';
export default class ProductCard extends LightningElement {
  @api
  updateProductStock(newStock) {
    this.stock = newStock;
  }
  stock = 0;
}

Other components can then call the updateProductStock function to modify the stock value of the ProductCard component.


Reactivity of Public Properties

Public properties in LWC are inherently reactive, meaning that whenever a public property's value changes, the component will automatically re-render. This reactivity ensures that the component's UI remains up-to-date with the latest property values.

For instance, if the price property changes, the ProductCard component will re-render to reflect the updated price. This ensures that the UI always displays the most recent information.


The Mutability of Public Properties

Public properties in LWC are generally considered read-only, meaning that, they should not be directly modified from within the component itself. This adheres to the unidirectional data flow principle (parent to child), promoting predictability and maintainability in component relationships.

Modifying a public property from within the component can lead to unexpected behavior and make it difficult to track the source of data changes. Instead, it's recommended to use property bindings or event-driven communication to update public properties.

However, there are specific use cases where modifying a public property within the component is justified, such as reflecting internal state changes.


No comments :
Post a Comment

Hi there, comments on this site are moderated, you might need to wait until your comment is published. Spam and promotions will be deleted. Sorry for the inconvenience but we have moderated the comments for the safety of this website users. If you have any concern, or if you are not able to comment for some reason, email us at rahul@forcetrails.com