1. What is Data Binding?
In Angular, a component usually has two main files:
app.component.ts— contains data, variables, functions, and logic.app.component.html— contains the visible user interface.
Data binding means connecting these two files.
Without binding
Your HTML is static. It shows fixed text. User actions do not affect component data automatically.
With binding
Your HTML becomes alive. It can show variables, react to clicks, update forms, and change styles.
| Binding Type | Direction | Syntax | Simple Meaning |
|---|---|---|---|
| Interpolation | Component to template | {{ value }} |
Show a value on the page. |
| Property binding | Component to template | [property]="value" |
Set an HTML or component property. |
| Event binding | Template to component | (event)="method()" |
Run code when the user does something. |
| Two-way binding | Both directions | [(ngModel)]="value" |
Keep input and variable synchronized. |
2. Setup: Create an Angular App
Start from a clean Angular project.
npm install -g @angular/cli
ng new data-binding-demo
cd data-binding-demo
ng serve
ng serve. Then open http://localhost:4200 in the browser.
You should see the Angular starter page or your application page.
Now open the project in Visual Studio Code.
code .
src/app/app.component.ts,
src/app/app.component.html,
src/app/app.component.css.
3. Interpolation: Show Component Data in HTML
Interpolation is the easiest Angular binding. It uses double curly braces:
{{ value }}.
Use it when you want to display text, numbers, calculated values, or method return values.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
imports: [],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
studentName = 'Champak';
courseName = 'Angular';
marks = 92;
getResult() {
return this.marks >= 40 ? 'Pass' : 'Fail';
}
}
<h1>Welcome, {{ studentName }}</h1>
<p>Course: {{ courseName }}</p>
<p>Marks: {{ marks }}</p>
<p>Result: {{ getResult() }}</p>
http://localhost:4200. You should see:
Welcome, Champak, Course: Angular, Marks: 92, and Result: Pass.
4. Property Binding: Control HTML Properties
Property binding sends data from the component to an HTML property. It uses square brackets.
export class AppComponent {
imageUrl = 'https://angular.io/assets/images/logos/angular/angular.png';
imageAlt = 'Angular logo';
buttonDisabled = true;
boxTitle = 'This title came from the component';
}
<img [src]="imageUrl" [alt]="imageAlt" width="120" />
<button [disabled]="buttonDisabled">
Submit
</button>
<div [title]="boxTitle">
Move your mouse over this box.
</div>
src, disabled, checked, value,
prefer property binding.
buttonDisabled is true.
5. Event Binding: React to User Actions
Event binding sends information from the template to the component. It uses round brackets.
export class AppComponent {
count = 0;
message = 'No button clicked yet.';
increase() {
this.count++;
this.message = 'Increase button clicked.';
}
decrease() {
this.count--;
this.message = 'Decrease button clicked.';
}
reset() {
this.count = 0;
this.message = 'Counter reset.';
}
}
<h2>Counter: {{ count }}</h2>
<button (click)="increase()">+ Increase</button>
<button (click)="decrease()">- Decrease</button>
<button (click)="reset()">Reset</button>
<p>{{ message }}</p>
Using Event Object
Sometimes you need details about the event. For example, the text typed by the user.
<input (input)="readText($event)" placeholder="Type something" />
<p>You typed: {{ typedText }}</p>
export class AppComponent {
typedText = '';
readText(event: Event) {
const inputElement = event.target as HTMLInputElement;
this.typedText = inputElement.value;
}
}
6. Two-Way Binding: Component and Input Stay Together
Two-way binding means the input field updates the component variable, and the component variable updates the input field.
Angular uses [(ngModel)] for common two-way form binding.
ngModel, you must import FormsModule.
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
imports: [FormsModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
username = '';
}
<label>
Enter your name:
<input [(ngModel)]="username" />
</label>
<h2>Hello, {{ username }}</h2>
What does [(ngModel)] mean?
The banana-in-a-box syntax is a shortcut.
<input [(ngModel)]="username" />
<input
[ngModel]="username"
(ngModelChange)="username = $event"
/>
7. Class Binding and Style Binding
Sometimes you do not only want to show data. You want to change design based on data.
Class Binding
export class AppComponent {
isPassed = true;
}
<p [class.success]="isPassed" [class.danger]="!isPassed">
Student result status
</p>
.success {
color: white;
background: green;
padding: 12px;
}
.danger {
color: white;
background: red;
padding: 12px;
}
Style Binding
export class AppComponent {
headingColor = 'darkorange';
fontSize = 32;
}
<h1 [style.color]="headingColor" [style.font-size.px]="fontSize">
Angular Data Binding
</h1>
8. Conditional Rendering with Binding
A real application must show and hide things depending on data.
export class AppComponent {
isLoggedIn = false;
login() {
this.isLoggedIn = true;
}
logout() {
this.isLoggedIn = false;
}
}
@if (isLoggedIn) {
<h2>Welcome back!</h2>
<button (click)="logout()">Logout</button>
} @else {
<h2>Please login.</h2>
<button (click)="login()">Login</button>
}
*ngIf. The newer control flow syntax uses
@if, but understanding both is useful.
<h2 *ngIf="isLoggedIn; else guest">Welcome back!</h2>
<ng-template #guest>
<h2>Please login.</h2>
</ng-template>
9. List Binding
Most applications show lists: products, students, lessons, orders, tasks, or comments.
export class AppComponent {
lessons = [
'Interpolation',
'Property Binding',
'Event Binding',
'Two-Way Binding',
'Class Binding',
'Style Binding'
];
}
<h2>Angular Data Binding Lessons</h2>
<ul>
@for (lesson of lessons; track lesson) {
<li>{{ lesson }}</li>
}
</ul>
List of Objects
export class AppComponent {
products = [
{ id: 1, name: 'Angular Course', price: 999, available: true },
{ id: 2, name: 'Java Course', price: 799, available: false },
{ id: 3, name: 'Python Course', price: 899, available: true }
];
}
<div class="product-card" *ngFor="let product of products">
<h3>{{ product.name }}</h3>
<p>Price: ₹{{ product.price }}</p>
<button [disabled]="!product.available">
{{ product.available ? 'Buy Now' : 'Out of Stock' }}
</button>
</div>
*ngFor, import CommonModule if you are using standalone components.
10. Form Binding
Forms are where data binding becomes extremely important. A form receives user data, validates it, displays errors, and finally submits it.
Simple Template-Driven Form
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
imports: [FormsModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
student = {
name: '',
email: '',
course: 'Angular'
};
submitForm() {
console.log('Form submitted:', this.student);
alert('Form submitted. Check the browser console.');
}
}
<form (ngSubmit)="submitForm()" #studentForm="ngForm">
<label>
Name:
<input
name="name"
[(ngModel)]="student.name"
required
/>
</label>
<label>
Email:
<input
name="email"
type="email"
[(ngModel)]="student.email"
required
/>
</label>
<label>
Course:
<select name="course" [(ngModel)]="student.course">
<option>Angular</option>
<option>Java</option>
<option>Python</option>
</select>
</label>
<button type="submit" [disabled]="studentForm.invalid">
Submit
</button>
</form>
<h3>Live Preview</h3>
<p>Name: {{ student.name }}</p>
<p>Email: {{ student.email }}</p>
<p>Course: {{ student.course }}</p>
11. Binding Between Parent and Child Components
In real Angular applications, one component sends data to another component.
@Input()
Parent sends data to child.
@Output()
Child sends an event to parent.
Create a Child Component
ng generate component student-card
src/app/student-card/student-card.component.ts,
student-card.component.html,
student-card.component.css.
Parent to Child with @Input()
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-student-card',
imports: [],
templateUrl: './student-card.component.html',
styleUrl: './student-card.component.css'
})
export class StudentCardComponent {
@Input() name = '';
@Input() course = '';
}
<div class="card">
<h3>{{ name }}</h3>
<p>Course: {{ course }}</p>
</div>
import { Component } from '@angular/core';
import { StudentCardComponent } from './student-card/student-card.component';
@Component({
selector: 'app-root',
imports: [StudentCardComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
studentName = 'Champak';
selectedCourse = 'Angular';
}
<app-student-card
[name]="studentName"
[course]="selectedCourse">
</app-student-card>
Child to Parent with @Output()
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-student-card',
imports: [],
templateUrl: './student-card.component.html',
styleUrl: './student-card.component.css'
})
export class StudentCardComponent {
@Input() name = '';
@Input() course = '';
@Output() selected = new EventEmitter<string>();
selectStudent() {
this.selected.emit(this.name);
}
}
<div class="card">
<h3>{{ name }}</h3>
<p>Course: {{ course }}</p>
<button (click)="selectStudent()">
Select Student
</button>
</div>
<app-student-card
[name]="studentName"
[course]="selectedCourse"
(selected)="showSelectedStudent($event)">
</app-student-card>
<p>Selected: {{ selectedStudent }}</p>
export class AppComponent {
studentName = 'Champak';
selectedCourse = 'Angular';
selectedStudent = '';
showSelectedStudent(name: string) {
this.selectedStudent = name;
}
}
12. Data Binding with Signals
Signals are a modern way to manage reactive state in Angular. A signal stores a value. When the signal changes, the template can update automatically.
import { Component, signal, computed } from '@angular/core';
@Component({
selector: 'app-root',
imports: [],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
count = signal(0);
doubleCount = computed(() => this.count() * 2);
increase() {
this.count.update(value => value + 1);
}
reset() {
this.count.set(0);
}
}
<h2>Count: {{ count() }}</h2>
<h3>Double: {{ doubleCount() }}</h3>
<button (click)="increase()">Increase</button>
<button (click)="reset()">Reset</button>
{{ count }}.
Signals are read like functions: {{ count() }}.
13. Common Mistakes and Fixes
| Mistake | Why It Happens | Fix |
|---|---|---|
Can't bind to 'ngModel' |
FormsModule is missing. |
Import FormsModule in the component. |
| Button not disabling | Used interpolation instead of property binding. | Use [disabled]="condition". |
| Method runs again and again | Method is called directly inside template. | Use a variable, computed value, pipe, or signal. |
| Input does not update variable | Only property binding was used. | Use [(ngModel)] or handle (input). |
| Child component does not receive data | @Input() missing or child not imported. |
Add @Input() and import child component. |
14. Mini Project: Student Course Registration Card
Now combine everything into one small project.
Features
- Student enters name.
- Student selects course.
- Preview updates live.
- Submit button is disabled until name is entered.
- Card style changes according to selected course.
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
imports: [FormsModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
studentName = '';
selectedCourse = 'Angular';
submitted = false;
courses = ['Angular', 'Java', 'Python', 'Data Structures'];
register() {
this.submitted = true;
}
reset() {
this.studentName = '';
this.selectedCourse = 'Angular';
this.submitted = false;
}
}
<main class="page">
<section class="form-box">
<h1>Course Registration</h1>
<label>
Student Name:
<input
[(ngModel)]="studentName"
placeholder="Enter student name"
/>
</label>
<label>
Course:
<select [(ngModel)]="selectedCourse">
@for (course of courses; track course) {
<option [value]="course">{{ course }}</option>
}
</select>
</label>
<button
(click)="register()"
[disabled]="studentName.trim().length === 0">
Register
</button>
<button (click)="reset()">Reset</button>
</section>
<section
class="preview-card"
[class.angular]="selectedCourse === 'Angular'"
[class.java]="selectedCourse === 'Java'"
[class.python]="selectedCourse === 'Python'"
[class.dsa]="selectedCourse === 'Data Structures'">
<h2>Live Preview</h2>
<p><strong>Name:</strong> {{ studentName || 'Not entered yet' }}</p>
<p><strong>Course:</strong> {{ selectedCourse }}</p>
@if (submitted) {
<p class="success">
Registration submitted successfully.
</p>
} @else {
<p>Fill the form and click register.</p>
}
</section>
</main>
.page {
min-height: 100vh;
padding: 40px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
background: #fff7ed;
font-family: Arial, sans-serif;
}
.form-box,
.preview-card {
background: white;
padding: 24px;
border-radius: 18px;
box-shadow: 0 14px 35px rgba(0, 0, 0, 0.12);
}
label {
display: block;
margin-bottom: 16px;
font-weight: bold;
}
input,
select {
display: block;
width: 100%;
margin-top: 8px;
padding: 12px;
border: 1px solid #999;
border-radius: 10px;
}
button {
margin-right: 10px;
padding: 12px 18px;
border: none;
border-radius: 999px;
background: #ff9933;
color: #1f1300;
font-weight: bold;
cursor: pointer;
}
button:disabled {
background: #bbb;
cursor: not-allowed;
}
.preview-card.angular {
border-top: 10px solid #dd0031;
}
.preview-card.java {
border-top: 10px solid #2563eb;
}
.preview-card.python {
border-top: 10px solid #facc15;
}
.preview-card.dsa {
border-top: 10px solid #16a34a;
}
.success {
color: green;
font-weight: bold;
}
@media (max-width: 800px) {
.page {
grid-template-columns: 1fr;
}
}
http://localhost:4200. You should see a registration form on one side
and a live preview card on the other side. Typing the name should update the preview.
Changing the course should change the card color.
15. Practice Tasks
- Create a counter with increase, decrease, and reset buttons.
- Create an input box where the typed text appears live below it.
- Create a password input and show “weak”, “medium”, or “strong” using class binding.
- Create a product card with image, price, and a disabled button when stock is zero.
- Create a student list using
@for. - Create a login/logout interface using
@if. - Create a parent component that sends course data to a child component.
- Create a child component button that sends a selected value back to the parent.
- Create a form with name, email, phone, and course.
- Create a mini shopping cart where quantity changes the total price.
16. Quick Quiz
{{ value }}(click)="method()"[(ngModel)]?
FormsModule@Input()?
@Output()?
Final Summary
Angular data binding is the foundation of Angular applications. Once you understand it, Angular stops feeling mysterious.
| Need | Use |
|---|---|
| Show data | {{ value }} |
| Set property | [property]="value" |
| Handle click or input | (event)="method()" |
| Bind form input both ways | [(ngModel)]="value" |
| Send data to child | @Input() |
| Send event to parent | @Output() |
| Reactive state | signal() |
After this lesson, the next natural topic is: Angular Forms 0 to Infinity, where template-driven forms and reactive forms can be studied deeply.