Angular 19 brings standalone components, signals, and a modern development experience for building enterprise-grade applications.
Overview
Angular 19 is ideal for complex, TypeScript-heavy projects that require strong typing, dependency injection, and comprehensive tooling.
Pre-installed Packages
- Angular 19: Latest Angular framework with standalone components
- Angular Material: Comprehensive Material Design component library
- Tailwind CSS: Utility-first CSS framework
- TypeScript: Strict mode enabled
- RxJS: Reactive programming library
- Angular CLI: Code generation and build tools
Key Features
- Standalone components (no NgModules required)
- Signals for reactive state management
- Dependency injection
- Two-way data binding
- Reactive forms
- Built-in validators
- Comprehensive testing utilities
Use Cases
Angular 19 is best suited for:
Enterprise Applications
Large-scale business applications with complex requirements
Admin Dashboards
Material Design admin panels with data tables and forms
Complex Forms
Applications with extensive form validation and reactive logic
TypeScript Projects
Projects requiring strong typing and compile-time safety
Angular Material Components
Angular Material provides a complete set of Material Design components that work seamlessly with Angular.
Available Components
- Layout: Card, Divider, Expansion Panel, Grid List, Stepper, Tabs
- Forms: Autocomplete, Checkbox, Datepicker, Input, Radio, Select, Slider, Slide Toggle
- Navigation: Menu, Sidenav, Toolbar
- Buttons & Indicators: Button, Button Toggle, Badge, Chips, Icon, Progress Bar, Progress Spinner
- Popups & Modals: Dialog, Snackbar, Tooltip
- Data Tables: Table, Paginator, Sort
Component Usage
Critical Rules
Standalone Components: Always use standalone: true in component decorators. NgModules are not used in ZapDev.
CommonModule: Import CommonModule for *ngIf, *ngFor, and other structural directives.
File Conventions
- Main component:
src/app/app.component.ts
- Component files:
component-name.component.ts (kebab-case)
- Service files:
service-name.service.ts (kebab-case)
- Components directory:
src/app/components/
- Services directory:
src/app/services/
- Models directory:
src/app/models/
Component Structure
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-component-name',
standalone: true,
imports: [CommonModule],
template: `
<div>
<!-- Template content -->
</div>
`,
styles: [`
/* Component styles or use Tailwind classes */
`]
})
export class ComponentNameComponent {
// Component logic
}
Project Structure
src/
├── app/
│ ├── app.component.ts # Main component
│ ├── components/ # Feature components
│ ├── services/ # Injectable services
│ └── models/ # TypeScript interfaces
├── styles.css # Global styles
└── main.ts # Bootstrap file
Signals for State Management
Angular 19 introduces signals for reactive state management:
Basic Signal
Computed Signal
import { Component, signal } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'app-root',
standalone: true,
imports: [MatButtonModule],
template: `
<div>
<p>Count: {{ count() }}</p>
<button mat-raised-button (click)="increment()">
Increment
</button>
</div>
`
})
export class AppComponent {
count = signal(0);
increment() {
this.count.update(value => value + 1);
}
}
import { Component, signal, computed } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div>
<p>Count: {{ count() }}</p>
<p>Doubled: {{ doubled() }}</p>
</div>
`
})
export class AppComponent {
count = signal(5);
doubled = computed(() => this.count() * 2);
}
RxJS Observables
For async operations, use RxJS:
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule],
template: `
<div *ngIf="data$ | async as data">
{{ data | json }}
</div>
`
})
export class AppComponent {
data$: Observable<any>;
constructor(private http: HttpClient) {
this.data$ = this.http.get('https://api.example.com/data');
}
}
Styling with Tailwind
Combine Angular Material with Tailwind utilities:
import { Component } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
@Component({
selector: 'app-root',
standalone: true,
imports: [MatCardModule],
template: `
<mat-card class="max-w-md mx-auto mt-8">
<mat-card-header class="bg-gradient-to-r from-blue-500 to-purple-600">
<mat-card-title class="text-white">Gradient Header</mat-card-title>
</mat-card-header>
<mat-card-content class="p-6">
<p class="text-gray-700">Custom styled card</p>
</mat-card-content>
</mat-card>
`
})
export class AppComponent {}
Best Practices
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class DataService {
getData() {
return ['item1', 'item2'];
}
}
// In component
constructor(private dataService: DataService) {}
Implement lifecycle hooks
import { Component, OnInit, OnDestroy } from '@angular/core';
export class AppComponent implements OnInit, OnDestroy {
ngOnInit() {
// Initialization logic
}
ngOnDestroy() {
// Cleanup logic
}
}
Use async pipe for observables
// Automatically subscribes and unsubscribes
<div *ngIf="data$ | async as data">
{{ data }}
</div>
Handle form validation properly