How to use two-way data binding in Angular

Two-way data binding is fundamental for creating reactive forms and synchronized user interfaces in Angular applications where data flows both from component to template and back. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented two-way data binding in countless Angular form components, input controls, and interactive elements for enterprise applications. From my expertise, the most powerful approach is to use ngModel directive with the banana-in-a-box syntax. This method provides automatic synchronization between component properties and form inputs, eliminating the need for manual event handling in most scenarios.

Use [(ngModel)] banana-in-a-box syntax for two-way data binding between component properties and form inputs.

import { Component } from '@angular/core'
import { FormsModule } from '@angular/forms'

@Component({
  selector: 'app-user-form',
  standalone: true,
  imports: [FormsModule],
  template: `
    <form>
      <div>
        <label>Name:</label>
        <input [(ngModel)]="user.name" name="name" type="text">
        <p>Hello, {{ user.name }}!</p>
      </div>

      <div>
        <label>Email:</label>
        <input [(ngModel)]="user.email" name="email" type="email">
      </div>

      <div>
        <label>Age:</label>
        <input [(ngModel)]="user.age" name="age" type="number">
      </div>

      <div>
        <label>Bio:</label>
        <textarea [(ngModel)]="user.bio" name="bio"></textarea>
      </div>

      <div>
        <label>
          <input [(ngModel)]="user.subscribed" name="subscribed" type="checkbox">
          Subscribe to newsletter
        </label>
      </div>

      <div>
        <h4>Current User Data:</h4>
        <pre>{{ user | json }}</pre>
      </div>
    </form>
  `
})
export class UserFormComponent {
  user = {
    name: '',
    email: '',
    age: null,
    bio: '',
    subscribed: false
  }
}

The [(ngModel)] syntax combines property binding [ngModel] and event binding (ngModelChange) into a single directive. When the input value changes, ngModel automatically updates the bound component property. When the component property changes programmatically, the input value updates to reflect the new state. This creates true two-way synchronization. The FormsModule must be imported to use ngModel. Each form control should have a unique name attribute for proper form handling.

Best Practice Note:

This is the same approach we use in CoreUI Angular form components for reactive user interfaces and data binding. Import FormsModule for template-driven forms or use ReactiveFormsModule with formControlName for reactive forms. Always provide name attributes for form controls and consider validation with Angular’s built-in validators.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.

Answers by CoreUI Core Team