Programmer's Picnic
Angular 0 to Infinity Series
Angular Lesson

Data Binding 0 to Infinity

Data binding is the bridge between your TypeScript logic and your HTML template. In Angular, it decides how data moves from component to screen, from screen to component, and between parent and child components.

By the end of this lesson, you will understand interpolation, property binding, event binding, two-way binding, class binding, style binding, form binding, component communication, and the common mistakes students make.

Beginner friendly Checkpoints included Angular examples High-contrast code

Component ↔ Template

Angular keeps your data and your view connected.

TypeScript value HTML screen
User click/input Component method
Form value Model value

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.
Google AdSense area. Use your ad unit slot: 7782388330

2. Setup: Create an Angular App

Start from a clean Angular project.

Terminal
npm install -g @angular/cli

ng new data-binding-demo

cd data-binding-demo

ng serve
Checkpoint 1: Type 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.

Terminal
code .
Checkpoint 2: These important files should exist:
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.

app.component.ts
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';
  }
}
app.component.html
<h1>Welcome, {{ studentName }}</h1>

<p>Course: {{ courseName }}</p>

<p>Marks: {{ marks }}</p>

<p>Result: {{ getResult() }}</p>
Checkpoint 3: Open http://localhost:4200. You should see:
Welcome, Champak, Course: Angular, Marks: 92, and Result: Pass.
Important: Do not put heavy calculations inside interpolation methods. Angular may call template methods many times during change detection.

4. Property Binding: Control HTML Properties

Property binding sends data from the component to an HTML property. It uses square brackets.

app.component.ts
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';
}
app.component.html
<img [src]="imageUrl" [alt]="imageAlt" width="120" />

<button [disabled]="buttonDisabled">
  Submit
</button>

<div [title]="boxTitle">
  Move your mouse over this box.
</div>
Interpolation vs Property Binding: For text display, use interpolation. For actual element properties such as src, disabled, checked, value, prefer property binding.
Checkpoint 4: The image should appear. The button should be disabled because buttonDisabled is true.

5. Event Binding: React to User Actions

Event binding sends information from the template to the component. It uses round brackets.

app.component.ts
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.';
  }
}
app.component.html
<h2>Counter: {{ count }}</h2>

<button (click)="increase()">+ Increase</button>

<button (click)="decrease()">- Decrease</button>

<button (click)="reset()">Reset</button>

<p>{{ message }}</p>
Checkpoint 5: Click the buttons. The counter should increase, decrease, and reset.

Using Event Object

Sometimes you need details about the event. For example, the text typed by the user.

app.component.html
<input (input)="readText($event)" placeholder="Type something" />

<p>You typed: {{ typedText }}</p>
app.component.ts
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.

Important: To use ngModel, you must import FormsModule.
app.component.ts
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 = '';
}
app.component.html
<label>
  Enter your name:
  <input [(ngModel)]="username" />
</label>

<h2>Hello, {{ username }}</h2>
Checkpoint 6: Type your name in the input box. The heading should update immediately.

What does [(ngModel)] mean?

The banana-in-a-box syntax is a shortcut.

Short version
<input [(ngModel)]="username" />
Expanded idea
<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

app.component.ts
export class AppComponent {
  isPassed = true;
}
app.component.html
<p [class.success]="isPassed" [class.danger]="!isPassed">
  Student result status
</p>
app.component.css
.success {
  color: white;
  background: green;
  padding: 12px;
}

.danger {
  color: white;
  background: red;
  padding: 12px;
}

Style Binding

app.component.ts
export class AppComponent {
  headingColor = 'darkorange';
  fontSize = 32;
}
app.component.html
<h1 [style.color]="headingColor" [style.font-size.px]="fontSize">
  Angular Data Binding
</h1>
Checkpoint 7: The heading should become dark orange and its font size should be 32 pixels.

8. Conditional Rendering with Binding

A real application must show and hide things depending on data.

app.component.ts
export class AppComponent {
  isLoggedIn = false;

  login() {
    this.isLoggedIn = true;
  }

  logout() {
    this.isLoggedIn = false;
  }
}
app.component.html
@if (isLoggedIn) {
  <h2>Welcome back!</h2>
  <button (click)="logout()">Logout</button>
} @else {
  <h2>Please login.</h2>
  <button (click)="login()">Login</button>
}
Older Angular projects: You may also see *ngIf. The newer control flow syntax uses @if, but understanding both is useful.
Older style with *ngIf
<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.

app.component.ts
export class AppComponent {
  lessons = [
    'Interpolation',
    'Property Binding',
    'Event Binding',
    'Two-Way Binding',
    'Class Binding',
    'Style Binding'
  ];
}
app.component.html
<h2>Angular Data Binding Lessons</h2>

<ul>
  @for (lesson of lessons; track lesson) {
    <li>{{ lesson }}</li>
  }
</ul>
Checkpoint 8: You should see a list of six data binding topics.

List of Objects

app.component.ts
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 }
  ];
}
app.component.html
<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>
For *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

app.component.ts
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.');
  }
}
app.component.html
<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>
Checkpoint 9: Type in the form. The live preview should update immediately. The submit button should remain disabled until required fields are filled.

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

Terminal
ng generate component student-card
Checkpoint 10: These files should be created:
src/app/student-card/student-card.component.ts, student-card.component.html, student-card.component.css.

Parent to Child with @Input()

student-card.component.ts
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 = '';
}
student-card.component.html
<div class="card">
  <h3>{{ name }}</h3>
  <p>Course: {{ course }}</p>
</div>
app.component.ts
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.component.html
<app-student-card
  [name]="studentName"
  [course]="selectedCourse">
</app-student-card>

Child to Parent with @Output()

student-card.component.ts
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);
  }
}
student-card.component.html
<div class="card">
  <h3>{{ name }}</h3>
  <p>Course: {{ course }}</p>

  <button (click)="selectStudent()">
    Select Student
  </button>
</div>
app.component.html
<app-student-card
  [name]="studentName"
  [course]="selectedCourse"
  (selected)="showSelectedStudent($event)">
</app-student-card>

<p>Selected: {{ selectedStudent }}</p>
app.component.ts
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.

app.component.ts
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);
  }
}
app.component.html
<h2>Count: {{ count() }}</h2>

<h3>Double: {{ doubleCount() }}</h3>

<button (click)="increase()">Increase</button>

<button (click)="reset()">Reset</button>
In a template, normal variables are written like {{ 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.
app.component.ts
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;
  }
}
app.component.html
<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>
app.component.css
.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;
  }
}
Final Project Checkpoint: Open 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

  1. Create a counter with increase, decrease, and reset buttons.
  2. Create an input box where the typed text appears live below it.
  3. Create a password input and show “weak”, “medium”, or “strong” using class binding.
  4. Create a product card with image, price, and a disabled button when stock is zero.
  5. Create a student list using @for.
  6. Create a login/logout interface using @if.
  7. Create a parent component that sends course data to a child component.
  8. Create a child component button that sends a selected value back to the parent.
  9. Create a form with name, email, phone, and course.
  10. Create a mini shopping cart where quantity changes the total price.

16. Quick Quiz

1. Which binding is used to show a variable in HTML?
Interpolation: {{ value }}
2. Which binding is used for button clicks?
Event binding: (click)="method()"
3. Which module is needed for [(ngModel)]?
FormsModule
4. What is the use of @Input()?
It allows a parent component to send data to a child component.
5. What is the use of @Output()?
It allows a child component to send events to a parent component.

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.

0%