Data binding in LWC

15 minute read
0
Sfdcpandaschool

Data binding is a core concept in LWC that allows developers to establish a relationship between a component's properties and the values displayed in its HTML template. This relationship ensures that the component's properties are always in sync with the values displayed in the template, and any changes made to one will be automatically reflected in the other.

In simple words when you map your data from the backend(JS) to the front end(HTML) that’s called data binding in LWC.

In LWC, there are two different data binding used -

One-way Data Binding: In one-way data binding, data flows in one direction, from the JavaScript controller to the HTML template. This means that changes in the JavaScript code are reflected in the UI, but changes in the UI do not automatically update the underlying data.

There are two main types of data binding in LWC:

1.One-Way Data Binding (Parent to Child):

One-way data binding allows you to pass data from a parent component to a child component. The parent component provides data as properties, and the child component receives and renders these properties. If the data in the parent component changes, the child component will automatically update to reflect those changes. However, changes in the child component's data do not affect the parent component.

In Lightning Web Components (LWC), one-way data binding is a technique where data flows in one direction, from the JavaScript controller to the component's markup (HTML). Changes in the JavaScript properties or variables automatically update the corresponding parts of the component's UI, but changes in the UI elements do not affect the source data. This is done to ensure that the UI always reflects the current state of the data source.

To access any javascript property in template, surround that property with curly braces.

@track property = ''; // in javascript

{property} // in template with no spaces

If a property is changed in template it doesn’t automatically update in javascript. For the javascript property to update we need to create an onchange() event in the template, handle it and change the value of property in javascript.

Event binding: This is used to bind an HTML element's event to a method in the component. To do this, we need to use the on-syntax followed by the event name and the name of the method to be called whenever the event is triggered. For example, Suppose, we have a button in a component and we want to call a method called "handleClick" when it is clicked, then we can bind the event like this:

<button on-click={handleClick}>Click me </button> Whenever the button is clicked, the "handleClick" method in the component will be called.

This is achieved by using attribute syntax in the parent component's markup to pass data to the child component. For example:

Parent component:

<template>
   {firstname}
   <lightning-input type="text" label="name" value={firstname}
   onchange={handlechange}></lightning-input>
</template>

Exp.js

import { LightningElement, track, api } from 'lwc';
export default class Sample extends LightningElement {
   @api firstname="hello";
   handlechange(event){
  console.log(this.firstname);  // This will not change even we change the view text data.   
   }
}

this.firstName = event.target.

this : If property is inside the class then use this. It specifies the current context

this.firstName : The variable name which we have defined at the beginning, we are just recalling it in the function to assign its changed value.

Here's how you can achieve one-way data binding in LWC:

Interpolation:You can use double curly braces {{ }} to bind a variable from your JavaScript controller to an element in your HTML template. For example:

 <template>
  <p>Hello, {{ greeting }}!</p>
</template>

        

In the JavaScript controller, you would have:

      import { LightningElement } from 'lwc';

export default class MyComponent extends LightningElement {
  greeting = 'World';
}
  
        

Direct Property Binding: You can bind properties of DOM elements to JavaScript properties using the data-* attribute. For example:

<template>
  <input type="text" data-id="myInput" value={inputValue} />
</template>

In the JavaScript controller:

        import { LightningElement } from 'lwc';

    export default class MyComponent extends LightningElement {
    inputValue = 'Initial Value';
   }

        

2.Two-Way Data Binding:

Two-way data binding in LWC will help users to exchange data from the controller to the template and form template to the controller. It will help users to establish communication bi-directionally.

Two-way data binding allows you to establish a bidirectional connection between a UI element and a JavaScript property. When the UI element changes, the associated JavaScript property is updated, and when the JavaScript property changes, the UI element is updated. LWC provides this functionality through the lightning-input component with the value property and the onchange event.

How to achieve Two-Way Data Binding?

The Lightning Web Components programming model has given us some decorators that add functionality to property or function.

  • @track is the decorator that helps us to track a private property's value and re-render a component when it changes.
  • Tracked properties are also called private reactive properties.
  • @track helps us to achieve two-way data binding
  • @track is powerful, but remember, track a property only if you want the component to re-render when the property's value changes. Don't track every private property.

In LWC, two-way data binding is primarily used with form elements like #lt;lightning-input#gt;, #lt;lightning-checkbox-group #gt;, and similar components. Here's a brief explanation of two-way data binding:UI-to-JavaScript Binding: When a user interacts with an input field or UI element (e.g., typing in a text field or checking a checkbox), the value of that UI element is automatically bound to a JavaScript property or variable.

JavaScript-to-UI Binding: Conversely, if the JavaScript property or variable associated with the UI element changes programmatically (e.g., through a function or data update), the UI element automatically reflects this change.

Here's a simplified example using a #lt;lightning-input#gt; component for two-way data binding:

<template>
    <lightning-card title="Two-Way Data Binding Example">
        <!-- Bind a JavaScript property to the input's value -->
        <lightning-input label="Name" value={name} onchange={handleNameChange}></lightning-input>
    </lightning-card>
</template>
   import { LightningElement, track } from 'lwc';

export default class TwoWayDataBindingExample extends LightningElement {
    @track name = '';

    // Event handler for input changes
    handleNameChange(event) {
        this.name = event.target.value; // Update the JavaScript property
    }
}   
      
Observe an Object’s Properties or an Array’s Elements

There is still one use case for @track. When a field contains an object or an array, there’s a limit to the depth of changes that are tracked. To tell the framework to observe changes to the properties of an object or to the elements of an array, decorate the field with @track.

Without using @track, the framework observes changes that assign a new value to a field. If the new value is not === to the previous value, the component rerenders.

To understand, let’s declare the fullName field, which contains an object with two properties, firstName and lastName.

fullName = { firstName : '', lastName : '' };

The framework observes changes that assign a new value to fullName. This code assigns a new value to the fullName field, so the component rerenders.

// Component rerenders.
this.fullName = { firstName : 'Mark', lastName : 'Doe' };

However, if we assign a new value to one of the object’s properties, the component doesn't rerender because the properties aren’t observed.

// Component doesn't rerender.
this.fullName.firstName = 'Mark';

The framework observes changes that assign a new value to the fullName field. This code doesn't do that, instead it assigns a new value to the firstName property of the fullName object.

To tell the framework to observe changes to the object's properties, decorate the fullName field with @track. Now if we change either property, the component rerenders.

// Component rerenders.
@track fullName = { firstName : '', lastName : '' };
this.fullName.firstName = 'Mark'; 

We can handle user input in forms using event handlers and data binding.

Event Handlers: LWC provides some built-in event handlers that we can use for handling user inputs, like - onClick, onChange, onSubmit, etc. For example, Suppose we want to handle a button click event, we can define an onClick event handler on the button element like this:

<lightning-button label="Submit" onclick={handleSubmit}></lightning-button>

In the component's JavaScript file, we can define the handleSubmit() method to handle the button click event like this:

handleSubmit(event) {
    // handle the button click event here
}

Data Binding: LWC has some data binding features inbuilt that help in binding the value of an input element to a property in the component state. We can use @track which keeps track of the values assigned to the property. And using this, we can handle user input. For example, suppose we need to bind the value of an input element to a property called firstName, then we can use the value attribute like this:

     import { LightningElement, track } from 'lwc';
    export default class MyComponent extends LightningElement {
    @track firstName = '';

    handleChange(event) {
        this.firstName = event.target.value;
    }
}   

The @track decorator is used to define the firstName property as a reactive property that causes the component to re-render whenever its value changes. The handleChange() method is called whenever the user inputs a new value, and it updates the firstName property in the component's state.

Post a Comment

0Comments
Post a Comment (0)