Use Angular Reactive Forms with an explicitly typed `FormGroup` and non-nullable controls. `validators.ts`: ```ts import { AbstractControl, ValidationErrors, ValidatorFn, } from '@angular/forms'; export const blockedEmailValidator: ValidatorFn = ( control: AbstractControl, ): ValidationErrors | null => { const email = String(control.value).toLowerCase(); return email.endsWith('@blocked.example') ? { blockedEmail: true } : null; }; ``` Component: ```ts import { Component, DestroyRef, inject, }...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add HoangNguyen0403/agent-skills-standard --skill angular-forms --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Angular Forms?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hoangnguyen0403-angular-forms-agent-skills-standard)More formats (shields.io, HTML) on the badges page.
Use Angular Reactive Forms with an explicitly typed `FormGroup` and non-nullable controls.
`validators.ts`:
```ts
import {
AbstractControl,
ValidationErrors,
ValidatorFn,
} from '@angular/forms';
export const blockedEmailValidator: ValidatorFn = (
control: AbstractControl,
): ValidationErrors | null => {
const email = String(control.value).toLowerCase();
return email.endsWith('@blocked.example')
? { blockedEmail: true }
: null;
};
```
Component:
```ts
import {
Component,
DestroyRef,
inject,
} from '@angular/core';
import {
FormBuilder,
FormControl,
FormGroup,
ReactiveFormsModule,
Validators,
} from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { blockedEmailValidator } from './validators';
type ProfileFormControls = {
name: FormControl<string>;
email: FormControl<string>;
};
@Component({
selector: 'app-profile-form',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form" (ngSubmit)="submit()">
<input formControlName="name" />
<input formControlName="email" type="email" />
<button type="submit" [disabled]="form.invalid">
Save
</button>
</form>
`,
})
export class ProfileFormComponent {
private readonly fb = inject(FormBuilder);
private readonly destroyRef = inject(DestroyRef);
readonly form: FormGroup<ProfileFormControls> =
this.fb.nonNullable.group({
name: ['', Validators.required],
email: [
'',
[Validators.required, Validators.email, blockedEmailValidator],
],
});
constructor() {
this.form.valueChanges
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((value) => {
// Sync `value` to a store or service here.
});
}
submit(): void {
if (this.form.invalid) {
this.form.markAllAsTouched();
return;
}
const value = this.form.getRawValue();
console.log(value); // { name: string; email: string }
}
}
```
`fb.nonNullable.group(...)` ensures the controls produce non-null string values. For complex inputs, prefer this strictly typed `FormGroup<T>` approach over an untyped `FormGroup` or template-driven forms.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!