---
name: angular
description: >
Angular best practices with TypeScript, RxJS, and modern patterns.
Trigger: When building Angular applications with TypeScript.
license: Apache-2.0
metadata:
author: poletron
version: "1.0"
scope: [root]
auto_invoke: "Working with angular"
## When to Use
Use this skill when:
- Building Angular 16+ applications
- Using standalone components
- Working with RxJS observables
- Implementing reactive forms
---
## Critical Patterns
### Standalone Components (REQUIRED)
```typescript
// ✅ ALWAYS: Use standalone components (Angular 16+)
@Component({
selector: 'app-user-card',
standalone: true,
imports: [CommonModule, RouterModule],
template: `
{{ user.name }}
`
})
export class UserCardComponent {
@Input({ required: true }) user!: User;
}
```
### Signals (RECOMMENDED)
```typescript
// ✅ Use signals for reactive state (Angular 16+)
@Component({...})
export class CounterComponent {
count = signal(0);
doubleCount = computed(() => this.count() * 2);
increment() {
this.count.update(n => n + 1);
}
}
```
### RxJS Best Practices (REQUIRED)
```typescript
// ✅ ALWAYS: Use async pipe, avoid manual subscriptions
@Component({
template: `
{{ user.name }}
`
})
export class UsersComponent {
users$ = this.userService.getUsers();
}
// ❌ NEVER: Manual subscribe without cleanup
ngOnInit() {
this.userService.getUsers().subscribe(users => {
this.users = users; // Memory leak risk!
});
}
```
---
## Decision Tree
```
Need component state? → Use signals
Need shared state? → Use service with BehaviorSubject
Need HTTP data? → Use HttpClient + async pipe
Need form validation? → Use Reactive Forms
Need lazy loading? → Use loadComponent()
```
---
## Code Examples
### Reactive Forms
```typescript
@Component({...})
export class UserFormComponent {
form = new FormGroup({
name: new FormControl('', [Validators.required]),
email: new FormControl('', [Validators.required, Validators.email]),
});
onSubmit() {
if (this.form.valid) {
this.userService.create(this.form.value);
}
}
}
```
### Service with State
```typescript
@Injectable({ providedIn: 'root' })
export class CartService {
private items = new BehaviorSubject([]);
items$ = this.items.asObservable();
addItem(item: CartItem) {
this.items.next([...this.items.value, item]);
}
}
```
---
## Commands
```bash
ng new myapp --standalone
ng serve
ng generate component users
ng build --configuration production
ng test
```