Angular is a TypeScript-based full framework developed and maintained by Google. With built-in routing, state management, HTTP client, and form handling, it is optimized for large-scale enterprise application development.
Angular's Core Philosophy
Unlike React or Vue, Angular is an Opinionated Full Framework. Its clearly defined structures and patterns ensure consistent code style even as team size grows.
- TypeScript native: Type safety and IDE support
- Dependency Injection (DI): Testability and modularity
- RxJS integration: Asynchronous data stream processing
- SSR support: Server-side rendering with Angular Universal
Component
The fundamental building block of Angular apps. Encapsulates templates, styles, and logic as a single unit.
import { Component, signal, computed } from '@angular/core';
@Component({
selector: 'app-counter',
standalone: true,
template: `
<div class="counter">
<p>Current count: {{ count() }}</p>
<p>Doubled: {{ doubled() }}</p>
<button (click)="increment()">+1</button>
<button (click)="decrement()">-1</button>
</div>
`,
})
export class CounterComponent {
count = signal(0);
doubled = computed(() => this.count() * 2);
increment() { this.count.update(v => v + 1); }
decrement() { this.count.update(v => v - 1); }
}
Dependency Injection
Angular's DI system automatically provides service instances to components. During testing, they can be easily replaced with mock objects, making unit testing straightforward.
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class PostService {
private readonly http = inject(HttpClient);
getPosts(): Observable<Post[]> {
return this.http.get<Post[]>('/api/posts');
}
}
@Component({ ... })
export class PostListComponent {
private readonly postService = inject(PostService);
posts = signal<Post[]>([]);
ngOnInit() {
this.postService.getPosts().subscribe(posts => this.posts.set(posts));
}
}
RxJS and Reactive Programming
Angular actively utilizes RxJS Observables for asynchronous processing. It provides powerful patterns for declaratively composing multiple async streams.
import { combineLatest } from 'rxjs';
import { map, debounceTime, switchMap } from 'rxjs/operators';
combineLatest([searchQuery$, filterCategory$])
.pipe(
debounceTime(300),
switchMap(([query, category]) =>
this.postService.search(query, category)
),
map(results => results.filter(p => p.published))
)
.subscribe(posts => this.posts.set(posts));
SSR and Progressive Hydration
Since Angular 17+, provideClientHydration(withEventReplay()) reuses server-rendered HTML on the client. This significantly improves FCP (First Contentful Paint).
// app.config.ts
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(withFetch()),
provideClientHydration(withEventReplay()),
],
};