Skip to main content

Components and Templates

Level: Beginner

ℹ️ What You'll Learn
  • Component structure and decorators
  • Template syntax (interpolation, binding)
  • Property binding and event binding
  • Two-way binding with ngModel
  • Component communication (Input/Output)
  • Component lifecycle

Why This Matters

Components = building blocks of Angular applications. Understanding components and templates is foundation for everything else. Every UI element = component.

Component Structure

import { Component } from '@angular/core';

@Component({
selector: 'app-student-card',
template: `
<div>
<h2>{{ student.name }}</h2>
<p>{{ student.rollNumber }}</p>
</div>
`,
styles: [`
div { padding: 10px; border: 1px solid #ccc; }
`]
})
export class StudentCardComponent {
student = {
name: 'Ravi Kumar',
rollNumber: '101'
};
}

@Component decorator configures component. selector = HTML tag to use. template = inline HTML (or templateUrl for external file). styles = inline CSS (or styleUrls for external files).

Template Syntax

Interpolation

<!-- app.component.html -->
<h1>{{ title }}</h1>
<p>{{ student.name }}</p>
<p>{{ getStudentClass() }}</p>

{{ }} = interpolation. Displays component property value.

Property Binding

<img [src]="imageUrl">
<button [disabled]="isSubmitting">Submit</button>
<div [class.active]="isActive">Active</div>
<div [style.color]="color">Text</div>

[property]="value" = bind component property to element property.

Event Binding

<button (click)="onSubmit()">Submit</button>
<input (keyup)="onKeyUp($event)">
<form (submit)="handleSubmit()">

(event)="handler()" = listen to element events.

Two-Way Binding

<input [(ngModel)]="studentName">
<!-- studentName updates when input changes, and vice versa -->

[(ngModel)] = two-way binding. Property and event combined.

Requires FormsModule import.

SMS Component Example

// student-form.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'app-student-form',
templateUrl: './student-form.component.html',
styleUrls: ['./student-form.component.css']
})
export class StudentFormComponent {
student = {
name: '',
email: '',
className: '10'
};

classes = ['9', '10', '11', '12'];
submitted = false;

onSubmit() {
if (this.student.name && this.student.email) {
console.log('Student:', this.student);
this.submitted = true;
this.resetForm();
}
}

resetForm() {
this.student = { name: '', email: '', className: '10' };
}
}
<!-- student-form.component.html -->
<form (ngSubmit)="onSubmit()">
<div>
<label>Name:</label>
<input
type="text"
[(ngModel)]="student.name"
name="name"
required
>
</div>

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

<div>
<label>Class:</label>
<select [(ngModel)]="student.className" name="className">
<option *ngFor="let cls of classes" [value]="cls">
{{ cls }}
</option>
</select>
</div>

<button type="submit" [disabled]="!student.name || !student.email">
Register
</button>
</form>

<div *ngIf="submitted">
Student {{ student.name }} registered!
</div>

Component Input/Output

Parent to Child (Input)

// parent.component.ts
export class StudentListComponent {
students = [
{ id: 1, name: 'Ravi', className: '10' },
{ id: 2, name: 'Priya', className: '10' }
];
}
<!-- parent.component.html -->
<app-student-card *ngFor="let student of students" [student]="student">
</app-student-card>
// student-card.component.ts
import { Component, Input } from '@angular/core';

@Component({
selector: 'app-student-card',
templateUrl: './student-card.component.html'
})
export class StudentCardComponent {
@Input() student: any;
}

@Input() = receive data from parent. [student]="student" = pass data to child.

Child to Parent (Output)

// student-card.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
selector: 'app-student-card',
templateUrl: './student-card.component.html'
})
export class StudentCardComponent {
@Input() student: any;
@Output() delete = new EventEmitter<number>();

onDelete() {
this.delete.emit(this.student.id);
}
}
<!-- student-card.component.html -->
<div>
<h3>{{ student.name }}</h3>
<button (click)="onDelete()">Delete</button>
</div>
<!-- parent.component.html -->
<app-student-card
*ngFor="let student of students"
[student]="student"
(delete)="onDeleteStudent($event)"
>
</app-student-card>
// parent.component.ts
onDeleteStudent(id: number) {
this.students = this.students.filter(s => s.id !== id);
}

@Output() = send event to parent. (delete)="handler($event)" = listen to child event.

Component Lifecycle

export class MyComponent implements OnInit, OnDestroy {
ngOnInit() {
// Called after component initialized
// Load data here
}

ngOnDestroy() {
// Called before component destroyed
// Cleanup here (unsubscribe, etc)
}
}

Common hooks:

  • ngOnInit — Initialize component
  • ngOnDestroy — Cleanup
  • ngOnChanges — Input changed
  • ngAfterViewInit — View rendered

Key Takeaways

  • Component = class + template + styles
  • Interpolation {{ }} displays values
  • Property binding [prop]="value" binds to element
  • Event binding (event)="handler()" listens to events
  • Two-way binding [(ngModel)]="property" both ways
  • @Input() = receive from parent
  • @Output() = send to parent
  • Lifecycle hooks for initialization/cleanup
💡 Backend Developer Tip

Angular components are like MVC views. Template = View, Component class = Controller/ViewModel. Familiar structure if you know ASP.NET MVC or Razor Pages.

⚠️ Common Mistakes
  1. Forgetting name attribute in form — ngModel won't work
  2. *Using object without trackBy in ngFor — Performance issue
  3. Forgetting to import FormsModule — ngModel not recognized
  4. Modifying Input directly — Child shouldn't modify @Input
  5. Not unsubscribing from Observables — Memory leaks
🤖Use AI to Learn Faster

Use ChatGPT, Claude, or Copilot to go deeper on Angular Components. Try these prompts:

  • "What's difference between property and event binding?"
  • "How do parent and child components communicate?"
  • "Why use @Input instead of passing in constructor?"
  • "Quiz me on component templates"

💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.

nexcoding.in