Data binding is an integral part of modern applications that get developed these days. Many frameworks and tools incorporate the data-binding technique to develop faster and easily debuggable applications. As a JavaScript developer, it is important to understand how this technique gets implemented in various JS frameworks and libraries. In this particular article, we are going to cover how this technique gets implemented in Angular and React. So what is data-binding?
The definition from Wikipedia states:
Data-binding is a technique that binds data sources from the provider and consumer together and synchronizes them.
The definition from Wikipedia is self-explanatory. But, let’s try and understand what data-binding means to React and Angular. Consider the following diagram:
Both React and Angular use components to render User interfaces. The point to remember while using React or Angular is that the component’s logic contains all the data related to a component that gets displayed in the view(UI). The connection between the component’s logic and the data it displays is called data-binding. Data-binding is of two types:
One-way data binding
As the name suggests, the data in this particular connection is bound one-way. One-way data-binding implies that only one of the following connections can be applied:
- Any change in the component’s logic (data) gets reflected inside the UI (view).
(or)
- Any change in the UI (view) gets reflected inside the component’s logic (model).
According to one-way data-binding, we can apply only one of the following connections:
Two-way data-binding
I think two-way data-binding now looks pretty straight forward. In two-way data-binding, the following connections are made at once:
- Change in the view gets reflected in the component’s logic.
(and)
- Change in the component’s logic gets reflected in the view.
Illustration of two-way data-binding:
As we can see in the above illustration, both connections are made at once i.e any change in view reflects in the component’s logic and any change in component’s logic reflects in the view. Now that we have discussed what data-binding actually means. Let’s understand how it works in React and Angular,
Data-binding in React
React was never really designed for two-way binding although two-way data-binding can be implemented in React. By default, the connection between a component and a view is always one-way bound. We can apply additional logic to a component so that the connection is made two-way. Let’s understand both bindings in react,
One-way data-binding in React
Like we stated before, one-way binding should perform one of the connections (View to Component or Component to View). In the case of React, we can only perform components to view connection. This means in React, by default there is no way that a view can change the component’s logic. Only the component’s logic can affect the view.
Component to View:
Example:
In the code above, we have built a component which displays a heading and a paragraph. Both these values are stored as state variables. The values of these variables are attached (bound) to the h3 and p elements respectively. As one can observe, any change in the value of the state variables is directly reflecting inside the view. By attaching the values of the state variables directly to the elements, we are implementing one-way data-binding in React.
View to Component:
Wait!! We just discussed above that React does not allow us to change the component’s logic from view. But, there’s a gotcha! React does not allow the view to change or update the component’s logic directly but, we can add event handlers to the view elements and change the component’s data. Let’s understand that with an example:
Consider the following component which allows us to change the model (Component) from the view:
function Component1() { let [inputValue,setInputValue] = useState(''); let changeValue = (e) => setInputValue(e.target.value); return ( <div> <input type=”text” onChange={changeValue} /> <p>Input Value: {inputValue}</p> </div> ); }
Similar to the previous example of component to view, we have bound the value of the input element to the state variable called inputValue. To implement the connection between the view and component, we have attached the onChange event to the input element. This event listens for any changes made to the input element by the user, inside the view. Then, the event calls the function changeValue( ), which sets the inputValue variable to the new updated value. To see the change inside the component, we have displayed the value of inputValue inside the paragraph element. We can see in the following example, any change made inside the view, reflects in the component:
Two-way data binding in React
Now that we understand both component to view and view to component connections, we can try and implement them together. How? Let’s understand that with an example:
Consider the following component which implements two-way data-binding:
function Component1() { let [inputValue,setInputValue] = useState(''); let changeValue = (e) => setInputValue(e.target.value); return ( <div> <input value={inputValue} onChange={changeValue} /> </div> ); }
We have used our knowledge of both the connections and used them here in the code above. By using component to view connection, we have bound the value of input element to the component variable inputValue and by using view to component connection, we have added the onChange event to the input element. This way, we can perform two-way data binding in React.
Data-binding in Angular
Unlike React, which is based on Flux architecture, Angular is based on the traditional MVVM architecture. Model (Component’s logic) and View (UI) are tightly coupled in Angular and due to this feature, we can easily implement two-way data-binding in Angular. Angular provides us the option to implement either one-way or two-way binding by default, meaning, the view can change/update the component’s logic and vice-versa. One-way or two-way binding can be implemented with very little effort.
Let’s implement.
One-way data-binding in Angular
Component to view:
There are two basic ways to implement connection from the component to view:
String interpolation:
In string interpolation, we use the double curly braces “{{ }}” to bind the value of the UI element to the component variable.
Example:
Component’s code:
export class AppComponent { articleHeading : string = ""; }
Component’s template:
<div> <h2>{{articleHeading}}</h2> </div>
One can see in the code below, any change made inside the component, reflects inside the view:
Property Binding:
In property binding, we can bind the property of the DOM element to the component’s variable using square brackets “[ ]”.
Example:
Component’s code:
export class AppComponent { inputValue: string = "This is an input"; }
Component’s template:
<div> <input type="text" [value]="inputValue" /> </div>
As one can observe, we have bound the inputValue to the input element using property binding “[ ]“.
View to Component:
We can use event handlers like we used in the React example to bind the view element to the component. In the following example we have bound the keyup event to the view element. The keyup event listens to any changes made by the user to the view element and calls the function changeInput which takes in the $event property of Angular. The $event property is used to capture the DOM event object. The function changeInput updates the value of the component variable.
Component code:
export class AppComponent { inputValue: string = ""; changeInput(event: any) { this.inputValue = event.target.value; } }
Component template:
<div> <input type="text" [value]="inputValue" (keyup)="changeInput($event)" /> </div>
Example to understand change in view results change in component:
Two-way data-binding in Angular
Like we discussed, Angular provides a default way to handle two-way binding. The combination of event-binding and property-binding is used for two-way binding in Angular, meaning, we use “[ ]” property-binding together with event-binding “( )” to implement two-way binding “[( )]”. Angular comes with a built-in directive called NgModel, which is part of the FormsModule. The NgModel directive provides us a simple way to perform two-way binding operations on DOM input elements, by adding [(ngModel)] attribute to the input elements. First, the [ ] (property-binding) binds the variable value to the view element and the ( ) (event-binding) listens to any changes made to the view element and updates the component variable.
Example:
Component’s code:
export class AppComponent { inputValue: string = ""; }
Component’s template:
<div> <input type="text" [(ngModel)]="inputValue" /> <p>{{inputValue}}</p> </div>
We can see in the code above, we have added the [(ngModel)] attribute which is bound to the variable inputValue. *Note- Don’t forget to import “FormsModule” inside app.module.ts and also add “FormsModule” to the imports array. So there you go, we have covered how data-binding (both one-way and two-way) can be implemented in React and Angular.