16.1 Introduction to Angular — A Complete Framework, TypeScript-Based, Version Evolution
What Is Angular?
Angular is an open-source front-end framework developed and maintained by Google. It is not merely a library — it is a full-featured framework capable of building large-scale web applications from start to finish.
AngularJS (Angular 1), released by Google in 2010, gained wide popularity with its declarative UI binding. However, it could not keep pace with modern web demands, so in 2016 it was completely rewritten as Angular 2. From Angular 2 onward, the framework is simply called "Angular."
What Angular Provides
| Feature | Description |
|---|---|
| Component-Based UI | Reusable UI building blocks |
| TypeScript by Default | Static typing, IDE support |
| Dependency Injection (DI) | Service management, testability |
| Angular Router | Built-in SPA routing |
| HttpClient | Built-in HTTP communication module |
| Forms | Template-driven / Reactive Forms |
| RxJS Integration | Asynchronous stream processing |
| Angular CLI | Project generation, build, test automation |
| Signals | New reactive state management (Angular 16+) |
Comparing Angular with React and Vue
This is the most common question for developers new to Angular.
| Aspect | Angular | React | Vue |
|---|---|---|---|
| Type | Complete Framework | UI Library | Framework |
| Language | TypeScript by default | JS / TS | JS / TS |
| Learning Curve | High | Medium | Low |
| Bundle Size | Medium~Large | Small | Small |
| State Management | Signals, RxJS (built-in) | External library needed | Pinia (separate) |
| HTTP | HttpClient (built-in) | External library | External library |
| Testing | Jasmine/Karma built-in | Jest (separate config) | Vitest (separate) |
| Maintained By | Meta | Community | |
| Best For | Enterprise, large teams | Various scales | Small-medium scale |
Key difference: Angular is a "batteries-included" package. React only handles UI — the rest is your choice.
Strengths of the TypeScript Foundation
Angular treats TypeScript as default, not optional.
// TypeScript advantage: compile-time error detection
interface User {
id: number;
name: string;
email: string;
}
// Type errors caught immediately
const user: User = {
id: 1,
name: 'Alice',
email: 'alice@example.com'
// phone: '010-...' // ❌ Compile error — not in User type
};
// Autocomplete and refactoring support
function greetUser(u: User): string {
return `Hello, ${u.name}!`; // IDE autocompletes id, name, email when typing u.
}
Benefits of TypeScript:
- Catch bugs before runtime
- Perfect IDE autocomplete
- Clear code intent in large teams
- Safe refactoring
Angular Version Evolution
AngularJS (2010) → "Angular 1"
- Revolutionized two-way data binding
- Performance and architecture limitations
Angular 2 (2016) → Complete rewrite
- TypeScript by default
- Component-based architecture
- RxJS integration
Angular 4~13 (2017~2021) → Incremental improvements
- Ivy renderer (Angular 9)
- Strict Mode by default
Angular 14 (2022) → Standalone Components (experimental)
- Components without NgModule
- inject() function introduced
Angular 15 (2022) → Standalone stabilized
- Directive Composition API
Angular 16 (2023) → Signals introduced (experimental)
- New reactive state management
- takeUntilDestroyed
Angular 17 (2023) → Modern Angular
- New control flow syntax (@if, @for, @switch)
- Deferrable Views (@defer)
- Signals stabilized
- New official docs (angular.dev)
Angular 18 (2024)
- Zoneless Change Detection (experimental)
- Material 3 complete
- Signal-based inputs stabilized
Angular 19 (2024)
- Incremental Hydration
- Route-level render mode
- Linked Signals
- Resource API (experimental)
Core Architecture
Angular applications are composed of several core concepts.
Angular App
├── Component ← UI unit
│ ├── Template (HTML)
│ ├── Class (TypeScript)
│ └── Styles (CSS/SCSS)
│
├── Service ← Business logic, data
│ └── @Injectable
│
├── Dependency Injection (DI) ← Service provision/consumption
│
├── Router ← URL ↔ Component mapping
│
└── Module (NgModule) / Standalone
└── Component grouping (pre-Angular 17 approach)
Component — The Basic UI Unit
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root', // Used as <app-root> in HTML
standalone: true, // Default in Angular 17+
template: `
<h1>{{ title }}</h1>
<p>Getting started with Angular {{ version }}</p>
`,
styles: [`
h1 { color: #dd0031; } /* Angular brand color */
`]
})
export class AppComponent {
title = 'My Angular App';
version = 19;
}
Service — Separating Business Logic
// user.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // Available as a singleton throughout the app
})
export class UserService {
private users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
getUsers() {
return this.users;
}
}
Basic Code Example — Hello Angular
// main.ts — App bootstrap
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent)
.catch(err => console.error(err));
// app/app.component.ts — Root component
import { Component, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<div class="container">
<h1>{{ title }}</h1>
<!-- Angular 17+ new control flow syntax -->
@if (isLoggedIn()) {
<p>Hello, {{ userName() }}!</p>
<button (click)="logout()">Logout</button>
} @else {
<button (click)="login()">Login</button>
}
<h2>User List</h2>
<ul>
@for (user of users(); track user.id) {
<li>{{ user.name }} (ID: {{ user.id }})</li>
} @empty {
<li>No users found.</li>
}
</ul>
</div>
`
})
export class AppComponent {
title = 'Angular 19 Demo';
// Signals — new reactive state management
isLoggedIn = signal(false);
userName = signal('');
users = signal([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
]);
login() {
this.isLoggedIn.set(true);
this.userName.set('Alice');
}
logout() {
this.isLoggedIn.set(false);
this.userName.set('');
}
}
Real-World Example — Mini Dashboard
A simple dashboard example showing how Angular is structured in production.
// dashboard/dashboard.component.ts
import { Component, OnInit, inject } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { Observable } from 'rxjs';
import { DashboardService } from './dashboard.service';
interface Stats {
totalUsers: number;
activeUsers: number;
revenue: number;
}
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [AsyncPipe],
template: `
<div class="dashboard">
<h1>Dashboard</h1>
@if (stats$ | async; as stats) {
<div class="stats-grid">
<div class="stat-card">
<h3>Total Users</h3>
<span class="number">{{ stats.totalUsers | number }}</span>
</div>
<div class="stat-card">
<h3>Active Users</h3>
<span class="number">{{ stats.activeUsers | number }}</span>
</div>
<div class="stat-card">
<h3>Revenue</h3>
<span class="number">{{ stats.revenue | currency:'USD' }}</span>
</div>
</div>
} @else {
<p>Loading data...</p>
}
</div>
`
})
export class DashboardComponent implements OnInit {
// DI via inject() function (Angular 14+ recommended)
private dashboardService = inject(DashboardService);
stats$!: Observable<Stats>;
ngOnInit() {
this.stats$ = this.dashboardService.getStats();
}
}
// dashboard/dashboard.service.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class DashboardService {
private http = inject(HttpClient);
getStats(): Observable<{ totalUsers: number; activeUsers: number; revenue: number }> {
// Real environment: return this.http.get('/api/stats');
// Mock data for example
return of({
totalUsers: 12847,
activeUsers: 3421,
revenue: 45000
}).pipe(delay(500)); // Network delay simulation
}
}
Projects Where Angular Shines
Angular excels in the following situations:
Best Fit
- Enterprise applications: ERP, CRM, admin dashboards
- Large teams: 5+ developers needing TypeScript and strong conventions
- Long-term maintenance: Google's LTS guarantee and migration tools
- Complete solution needed: Routing, HTTP, Forms, state management all built-in
- Banking/finance systems: Used by Google, YouTube, Wix, etc.
Use With Caution
- Small simple apps: High configuration overhead
- First framework for beginners: Steep learning curve
- Quick prototypes: React/Vue are faster to start
Pro Tips
Tip 1: Install Angular DevTools
Install the Angular DevTools extension in Chrome/Firefox to visually inspect the component tree, change detection, and profiling.
Tip 2: Understand the Release Cycle
Angular releases a major version every 6 months. LTS (Long-Term Support) is guaranteed for 18 months. Use ng update to migrate easily.
# Check available updates
ng update
# Update to a specific version
ng update @angular/core@19 @angular/cli@19
Tip 3: angular.dev is the Official Docs
Since 2023, the official documentation has moved to angular.dev. The old angular.io is no longer updated.
Tip 4: Standalone Components Are the Future
Since Angular 17, the default for ng new is Standalone Components. NgModule-based development is considered legacy. Always start new projects with Standalone.
Summary
| Concept | Key Point |
|---|---|
| Angular | Google's complete TypeScript framework |
| Versions | 6-month release cycle, currently Angular 19 |
| Architecture | Components + Services + DI + Router |
| Modern Trends | Standalone components, Signals, new control flow |
| Best For | Enterprise, large teams, long-term projects |
The next chapter sets up a real project using Angular CLI and explores its structure.