angular-forms
/angular-forms
Angular Reactive Forms with validators, FormArray, and dynamic forms. Covers typed forms, custom validators, and form patterns. USE WHEN: user mentions "Angular forms", "reactive forms", "FormGroup", "FormArray", "validators", "form validation", "Angular form patterns" DO NOT USE FOR: React forms - use `react-hook-form` or `react-forms`, template-driven forms for simple cases
- Author
- claude-dev-suite ↗
- Repository
- claude-dev-suite ↗
- Licence
- MIT
- Last repository change
- 21.10.2026
Assessment and security
- Files in this package
- 1
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 21.10.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
What it does and when to use it
Angular Reactive Forms with validators, FormArray, and dynamic forms. Covers typed forms, custom validators, and form patterns. USE WHEN: user mentions "Angular forms", "reactive forms", "FormGroup", "FormArray", "validators", "form validation", "Angular form patterns" DO NOT USE FOR: React forms - use `react-hook-form` or `react-forms`, template-driven forms for simple cases
Triggers from the description
Original author description
Angular Reactive Forms with validators, FormArray, and dynamic forms. Covers typed forms, custom validators, and form patterns. USE WHEN: user mentions "Angular forms", "reactive forms", "FormGroup", "FormArray", "validators", "form validation", "Angular form patterns" DO NOT USE FOR: React forms - use `react-hook-form` or `react-forms`, template-driven forms for simple cases
How it works
- Typed Reactive Forms (Angular 14+)
- FormArray
- Custom Validators
- Error Display Pattern
- Anti-Patterns
- Quick Troubleshooting
SKILL.md preview
---
name: angular-forms
description: |
Angular Reactive Forms with validators, FormArray, and dynamic forms.
Covers typed forms, custom validators, and form patterns.
USE WHEN: user mentions "Angular forms", "reactive forms", "FormGroup", "FormArray",
"validators", "form validation", "Angular form patterns"
DO NOT USE FOR: React forms - use `react-hook-form` or `react-forms`,
template-driven forms for simple cases
allowed-tools: Read, Grep, Glob, Write, Edit
---
# Angular Forms - Quick Reference
> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `angular`, topic: `forms` for comprehensive documentation.
## Typed Reactive Forms (Angular 14+)
```typescript
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
@Component({
standalone: true,
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input formControlName="name" />
<input formControlName="email" type="email" />
<button type="submit" [disabled]="form.invalid">Save</button>
</form>
`
})
export class UserFormComponent {
private fb = inject(FormBuilder);
form = this.fb.nonNullable.group({
name: ['', [Validators.required, Validators.minLength(2)]],
email: ['', [Validators.required, Validators.email]],
age: [0, [Validators.min(0), Validators.max(150)]],
});
onSubmit() {
if (this.form.valid) {
const value = this.form.getRawValue(); // Typed!
console.log(value.name); // string, not string | null
}
}
}
```
## FormArray
```typescript
form = this.fb.group({
name: ['', Validators.required],
addresses: this.fb.array([this.createAddress()]),
});
createAddress() {
return this.fb.group({
street: ['', Validators.required],
city: ['', Validators.required],
zip: ['', [Validators.required, Validators.pattern(/^\d{5}$/)]],
});
}
get addresses() {
return this.form.get('addresses') as FormArray;
}
addAddress() {
this.addresses.push(this.createAddress());
}
removeAddress(index: number) {
this.addresses.removeAt(index);
}
```
## Custom Validators
```typescript
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
// Sync validator
export function forbiddenName(name: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const forbidden = control.value === name;
return forbidden ? { forbiddenName: { value: control.value } } : null;
};
}
// Async validator
export function uniqueEmail(userService: UserService): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
return userService.checkEmail(control.value).pipe(
map(exists => exists ? { emailTaken: true } : null),
catchError(() => of(null))
);
};
}
// Cross-field validator
export const passwordMatchValidator: ValidatorFn = (form: AbstractControl) => {
const password = form.get('password')?.value;
const confirm = form.get('confirmPassword')?.value;
return password === confirm ? null : { passwordMismatch: true };
};
```
## Error Display Pattern
```typescript
@Component({
template: `
<input formControlName="email" />
@if (form.controls.email.hasError('required') && form.controls.email.touched) {
<span class="error">Email is required</span>
}
@if (form.controls.email.hasError('email') && form.controls.email.touched) {
<span class="error">Invalid email format</span>
}
`
})
```
## Anti-Patterns
| Anti-Pattern | Why It's Bad | Correct Approach |
|--------------|--------------|------------------|
| Template-driven for complex forms | Hard to test, no type safety | Use reactive forms |
| Not using `nonNullable` | Nullable types everywhere | Use `fb.nonNullable.group()` |
| Validation in component | Not reusable | Extract to validator functions |
| Subscribing to valueChanges without cleanup | Memory leaks | Use `takeUntilDestroyed()` |
## Quick Troubleshooting
| Issue | Likely Cause | Solution |
|-------|--------------|----------|
| Form always invalid | Missing required field value | Check initial values |
| Type errors with controls | Using untyped FormGroup | Use `fb.nonNullable.group()` |
| Async validator fires too often | No debounce | Add `updateOn: 'blur'` |
| FormArray changes not reflected | Missing trackBy | Use track in `@for` |
Versions
| Repository | Score | Licence |
|---|---|---|
| This page · claude-dev-suite/claude-dev-suite | 95 | MIT |
| aratkruglik/claude-sdlc | 100 | MIT |
| HoangNguyen0403/agent-skills-standard | 100 | MIT |
Database snapshot: 13.11.2026 · package version ea54ae897018 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 80Angular v21 FormArray Directive Conflict
Review Angular 21 apps for custom FormArray or formArray directive and input naming conflicts after the upgrade. Use when custom directives or inputs collide with Angular reactive forms APIs. - 100react-forms
React form handling patterns and best practices. Covers controlled vs uncontrolled forms, React Hook Form, form validation, complex form patterns, and Server Actions forms. USE WHEN: user mentions "React forms", "controlled inputs", "uncontrolled inputs", "form validation",… - 80Angular v22 Signal Forms
Use this skill when an Angular 22 app is adopting Signal Forms or needs to align form code with stricter template and validation rules. - 100react-hook-form-zod-patterns
Type-safe forms with react-hook-form and Zod validation — multi-step flows, mode switching, error display, schema composition. Use when building forms with runtime validation or multi-step signup/checkout. - 100ng-implementation
Angular 21+ implementation and review rules (standalone, signals, DI, forms). Use when writing or changing Angular code. - 100fec-form-handling
Use when building or reviewing substantial forms with React Hook Form, Zod schemas, typed validation, dynamic fields, controlled third-party inputs, file upload, multi-step flows, dependent validation, or form performance. Do not use for trivial 1-3 field forms without…