1. Introduction to Angular Components
A component is the basic visual building block of an Angular application. A complete Angular app is not usually one giant page. It is a tree of small components: header, footer, cards, lists, forms, pages, dashboards, and dialogs.
Angular App
├── Header Component
├── Home Page Component
│ ├── Course Card Component
│ └── Testimonial Component
└── Footer Component
Checkpoint: Verify before continuing
Complete all checks to continue.
2. Component Mental Model
Think of a component as a small machine. It receives data, displays data, reacts to events, and may send data back to another component.
Checkpoint
Complete all checks to continue.
3. Generate Your First Component
The safest way to create a component is through Angular CLI. The CLI creates the TypeScript, HTML, CSS, and test files in the correct structure.
Command
ng generate component components/course-card
Short Form
ng g c components/course-card
Expected Files
src/app/components/course-card/
├── course-card.ts
├── course-card.html
├── course-card.css
└── course-card.spec.ts
.ts file and use the exact exported class name.
Checkpoint
Complete all checks to continue.
4. Anatomy of a Component
A component is a TypeScript class decorated with @Component.
The decorator tells Angular how to use that class as a visual component.
import { Component } from '@angular/core';
@Component({
selector: 'app-course-card',
templateUrl: './course-card.html',
styleUrl: './course-card.css'
})
export class CourseCard {
title = 'Angular Components';
level = 'Beginner';
}
| Part | Meaning | Example |
|---|---|---|
selector |
Custom HTML tag for the component. | <app-course-card> |
templateUrl |
HTML file for the view. | ./course-card.html |
styleUrl |
CSS file for this component. | ./course-card.css |
export class |
TypeScript logic and data. | CourseCard |
Checkpoint
Complete all checks to continue.
5. Display a Component on the Page
To show a component, place its selector in another component's template. In standalone Angular, also import the child component in the parent component.
course-card.html
<article class="course-card">
<h3>{{ title }}</h3>
<p>Level: {{ level }}</p>
</article>
app.ts or parent component
import { Component } from '@angular/core';
import { CourseCard } from './components/course-card/course-card';
@Component({
selector: 'app-root',
imports: [CourseCard],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {}
app.html
<h1>Angular Component Practice</h1>
<app-course-card></app-course-card>
Checkpoint
Complete all checks to continue.
6. Component Styling
Component CSS is normally scoped to that component. This helps avoid accidental style collisions.
course-card.css
.course-card {
max-width: 360px;
padding: 18px;
border: 1px solid #fed7aa;
border-radius: 18px;
background: #fff7ed;
}
.course-card h3 {
color: #92400e;
margin-top: 0;
}
src/styles.css. Keep component-specific rules in the component CSS
file.
Checkpoint
Complete all checks to continue.
7. Data and Methods Inside Components
Component properties hold data. Component methods respond to user actions.
course-card.ts
export class CourseCard {
title = 'Angular Components';
enrolled = false;
enroll(): void {
this.enrolled = true;
}
}
course-card.html
<article class="course-card">
<h3>{{ title }}</h3>
@if (enrolled) {
<p>You are enrolled.</p>
} @else {
<button (click)="enroll()">Enroll</button>
}
</article>
Checkpoint
Complete all checks to continue.
8. Components with Signals
A signal is reactive state. When a signal changes, Angular can update the places where that signal is used.
course-card.ts
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-course-card',
templateUrl: './course-card.html',
styleUrl: './course-card.css'
})
export class CourseCard {
likes = signal(0);
like(): void {
this.likes.update(value => value + 1);
}
}
course-card.html
<p>Likes: {{ likes() }}</p>
<button (click)="like()">
Like
</button>
Checkpoint
Complete all checks to continue.
9. Parent to Child Data with input()
A parent component can send data into a child component.
Modern Angular supports the input() function for declaring component inputs.
course-card.ts
import { Component, input } from '@angular/core';
@Component({
selector: 'app-course-card',
templateUrl: './course-card.html',
styleUrl: './course-card.css'
})
export class CourseCard {
title = input.required<string>();
level = input('Beginner');
}
course-card.html
<article class="course-card">
<h3>{{ title() }}</h3>
<p>Level: {{ level() }}</p>
</article>
parent template
<app-course-card
title="Angular Components"
level="Level 0 to Infinity">
</app-course-card>
@Input(). Both styles exist, but input() is the
modern signal-based approach.
Checkpoint
Complete all checks to continue.
10. Child to Parent Events with output()
A child component can send an event to its parent. Modern Angular uses the output() function
for custom events.
course-card.ts
import { Component, input, output } from '@angular/core';
@Component({
selector: 'app-course-card',
templateUrl: './course-card.html',
styleUrl: './course-card.css'
})
export class CourseCard {
title = input.required<string>();
selected = output<string>();
selectCourse(): void {
this.selected.emit(this.title());
}
}
course-card.html
<button (click)="selectCourse()">
Select Course
</button>
parent template
<app-course-card
title="Angular Components"
(selected)="onCourseSelected($event)">
</app-course-card>
parent TypeScript
message = '';
onCourseSelected(courseTitle: string): void {
this.message = `Selected: ${courseTitle}`;
}
Checkpoint
Complete all checks to continue.
11. Two-way Component Binding with model()
A custom child component can support two-way binding using model().
This is useful for reusable controls like rating boxes, counters, filters, and toggles.
rating-box.ts
import { Component, model } from '@angular/core';
@Component({
selector: 'app-rating-box',
template: `
<p>Rating: {{ rating() }}</p>
<button (click)="increase()">+</button>
`
})
export class RatingBox {
rating = model(0);
increase(): void {
this.rating.update(value => value + 1);
}
}
parent template
<app-rating-box [(rating)]="courseRating"></app-rating-box>
<p>Parent Rating: {{ courseRating }}</p>
Checkpoint
Complete all checks to continue.
12. Content Projection with ng-content
Content projection lets a parent put custom content inside a child component. This is useful for reusable cards, panels, modals, and layouts.
panel.html
<section class="panel">
<header>
<ng-content select="[panel-title]"></ng-content>
</header>
<div class="panel-body">
<ng-content></ng-content>
</div>
</section>
parent template
<app-panel>
<h2 panel-title>Angular Course</h2>
<p>This paragraph is projected into the panel body.</p>
</app-panel>
Checkpoint
Complete all checks to continue.
13. Component Lifecycle
A component has a lifecycle: Angular creates it, initializes inputs, checks changes, renders it, and finally destroys it when it is no longer needed.
| Hook | When it runs | Common use |
|---|---|---|
constructor |
When class is created. | Basic setup, dependency injection. |
ngOnInit |
After inputs are initialized. | Load initial data. |
ngOnChanges |
When inputs change. | React to parent input changes. |
ngOnDestroy |
Before component is destroyed. | Cleanup subscriptions or timers. |
afterNextRender |
After next full render. | DOM-dependent work. |
Example
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-timer-box',
template: '<p>Timer running</p>'
})
export class TimerBox implements OnInit, OnDestroy {
private timerId = 0;
ngOnInit(): void {
this.timerId = window.setInterval(() => {
console.log('tick');
}, 1000);
}
ngOnDestroy(): void {
window.clearInterval(this.timerId);
}
}
Checkpoint
Complete all checks to continue.
14. Referencing Child Elements with viewChild()
Sometimes a component needs a reference to an element or child component in its own template. Angular supports view queries for this.
Example
import { Component, ElementRef, viewChild } from '@angular/core';
@Component({
selector: 'app-focus-box',
template: `
<input #nameInput placeholder="Name">
<button (click)="focusName()">Focus Input</button>
`
})
export class FocusBox {
nameInput = viewChild.required<ElementRef<HTMLInputElement>>('nameInput');
focusName(): void {
this.nameInput().nativeElement.focus();
}
}
Checkpoint
Complete all checks to continue.
15. Page Components vs Reusable Components
A clean Angular app separates route-level page components from smaller reusable UI components.
| Type | Meaning | Examples |
|---|---|---|
| Page component | Connected to a route. | Home, Courses, Contact, Dashboard. |
| Reusable component | Used inside many pages. | Header, Footer, CourseCard, RatingBox. |
| Smart component | Loads or manages data. | CoursesPage. |
| Presentational component | Receives data and displays UI. | CourseCard. |
Recommended Structure
src/app/
├── pages/
│ ├── home/
│ └── courses/
├── components/
│ ├── header/
│ ├── footer/
│ └── course-card/
└── services/
└── course.service.ts
Checkpoint
Complete all checks to continue.
16. Dynamic Component Rendering
Most components are used directly in templates. Advanced apps can render components dynamically. This is useful for dashboards, plugin-style UIs, modals, or switching between component types.
Using NgComponentOutlet
import { Component } from '@angular/core';
import { NgComponentOutlet } from '@angular/common';
import { AdminCard } from './admin-card/admin-card';
import { StudentCard } from './student-card/student-card';
@Component({
selector: 'app-dynamic-demo',
imports: [NgComponentOutlet],
template: `
<button (click)="useAdmin()">Admin</button>
<button (click)="useStudent()">Student</button>
<ng-container *ngComponentOutlet="selectedComponent"></ng-container>
`
})
export class DynamicDemo {
selectedComponent = StudentCard;
useAdmin(): void {
this.selectedComponent = AdminCard;
}
useStudent(): void {
this.selectedComponent = StudentCard;
}
}
Checkpoint
Complete all checks to continue.
17. Testing Components
Component tests verify that the component can be created and that important behavior works.
Basic Test Shape
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CourseCard } from './course-card';
describe('CourseCard', () => {
let component: CourseCard;
let fixture: ComponentFixture<CourseCard>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CourseCard]
}).compileComponents();
fixture = TestBed.createComponent(CourseCard);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Run Tests
ng test
Checkpoint
Complete all checks to continue.
18. Deployment Check for Components
After making components, build and deploy the full Angular app. Your custom domain is:
https://angular.learnwithchampak.live/
Build
npm run build:github
Deploy
npm run deploy:github
--base-href=/, not --base-href=/repo-name/.
Checkpoint
Complete all checks to continue.
19. Common Component Mistakes
| Mistake | Problem | Fix |
|---|---|---|
| Forgetting to import child component | Selector is not recognized. | Add child component to parent imports. |
| Using wrong selector | Component does not appear. | Copy selector from generated .ts file. |
| Wrong exported class name | Import error. | Use exact class name from generated file. |
| Too much logic in one component | Hard to maintain. | Split into smaller components and services. |
| Editing generated test imports blindly | Tests fail. | Make tests match standalone component imports. |
| Putting API logic in every component | Repeated code. | Move API calls to services. |
Checkpoint
Complete all checks to continue.
20. Student Assignment
Build a small component-based Angular page for a course website.
Create Components
ng g c components/site-header
ng g c components/site-footer
ng g c components/course-card
ng g c components/rating-box
ng g c pages/components-practice
Requirements
1. Show SiteHeader at the top.
2. Show three CourseCard components.
3. Pass course title using input().
4. Send selected course back to parent using output().
5. Add RatingBox using model().
6. Use component CSS for card design.
7. Add one ng-content based reusable panel.
8. Build successfully.
9. Deploy to angular.learnwithchampak.live.
Final Test
ng serve
Open:
http://localhost:4200
Final Checkpoint
Complete all checks to finish.
Final Summary
| Question | Answer |
|---|---|
| What is an Angular component? | A reusable UI building block with TypeScript, HTML, and CSS. |
| Which command creates a component? | ng generate component component-name |
| How do we show a child component? | Use its selector in the parent template and import it in the parent component. |
| How does parent send data to child? | Use input() or @Input(). |
| How does child send events to parent? | Use output() or @Output(). |
| How can a custom child support two-way binding? | Use model(). |
| What supports projected content? | <ng-content> |
| What is a good structure? | Put pages in pages and reusable UI in components or
shared/components.
|