Use a standalone `ValidatorFn` in `validators.ts`, then attach it to a strictly typed reactive form. ```ts // validators.ts import { AbstractControl, ValidationErrors, ValidatorFn, } from '@angular/forms'; export function forbiddenName(name: string): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { const value = String(control.value ?? '').trim().toLowerCase(); return value === name.toLowerCase() ? { forbiddenName: { value: control.value } } : null; }; } ``` ```ts...
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-da7de313)More formats (shields.io, HTML) on the badges page.
Use a standalone `ValidatorFn` in `validators.ts`, then attach it to a strictly typed reactive form.
```ts
// validators.ts
import {
AbstractControl,
ValidationErrors,
ValidatorFn,
} from '@angular/forms';
export function forbiddenName(name: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const value = String(control.value ?? '').trim().toLowerCase();
return value === name.toLowerCase()
? { forbiddenName: { value: control.value } }
: null;
};
}
```
```ts
// profile.component.ts
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { forbiddenName } from './validators';
interface ProfileForm {
username: string;
email: string;
}
export class ProfileComponent {
readonly form: FormGroup<ProfileForm>;
constructor(private readonly fb: FormBuilder) {
this.form = this.fb.nonNullable.group({
username: ['', [Validators.required, forbiddenName('admin')]],
email: ['', [Validators.required, Validators.email]],
});
}
submit(): void {
if (this.form.invalid) {
this.form.markAllAsTouched();
return;
}
console.log(this.form.getRawValue());
}
}
```
Display the custom error in the template:
```html
<input formControlName="username" />
@if (form.controls.username.hasError('forbiddenName')) {
<p>This username is not allowed.</p>
}
```
`null` means valid; returning an object such as `{ forbiddenName: ... }` makes the control invalid. This uses Reactive Forms, `FormGroup<T>`, `fb.nonNullable.group(...)`, and keeps validation logic outside the component class.
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!