Angular Two-Way Binding: [(ngModel)]
![Angular Two-Way Binding: [(ngModel)]](/_next/image?url=https%3A%2F%2Fangular.dev%2Fassets%2Fimages%2Fng-image.jpg&w=1600&q=75)
Think of [(ngModel)] as a walkie-talkie for data, syncing a component property with a template view. It's used in forms where user input immediately updates a variable, and vice-versa. The footgun is overusing it, which creates tangled data flows.
WHY IT EXISTS Building interactive forms requires keeping the user interface (the view) and the application's internal state (the model) in perfect sync. Manually writing event listeners for every keystroke and then separately writing code to update the input's value is repetitive and error-prone. Two-way binding was created to automate this synchronization.
THE MENTAL MODEL Imagine a walkie-talkie connecting your component's data property (like username) and an input field in your HTML. When the user types in the input, they're talking into one walkie-talkie, and the username property hears it and updates. When your code changes the username property, it talks into its walkie-talkie, and the input field on the screen updates. They are always in sync.
HOW IT WORKS The [(ngModel)] syntax is actually a shortcut, or "syntactic sugar," for two separate bindings. The square brackets [ngModel] handle property binding, pushing data from the component to the view. The parentheses (ngModelChange) handle event binding, listening for changes in the view and pushing them back to the component. Together, [()], often called "banana in a box," creates the two-way flow. To use it, you must also import the FormsModule into your Angular module.
WHEN TO USE IT Use [(ngModel)] for simple form-based scenarios where immediate, direct synchronization between a view element and a component property is desired. It's perfect for things like settings toggles, search bars, or basic data entry fields in a prototype or a small, self-contained component.
WHEN NOT TO USE IT Avoid [(ngModel)] in complex components or when managing shared state. Its implicitness can create hard-to-debug situations where you don't know what caused a state change. In larger applications, a more explicit, one-way data flow (using property binding for input and event binding for output separately) is often preferred for maintainability and clearer state management.
ONE CANONICAL EXAMPLE To bind a user's name to an input field, you would have this in your component's TypeScript file: export class UserProfileComponent { username: string = 'Alice'; }. In your corresponding HTML template, you would write: <input [(ngModel)]="username">. Now, the input field will initially display "Alice". If the user types "Bob" into the field, the username property in the component will automatically become "Bob".
Read the original → angular.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.