This is my implementation.
File: src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
genders = ['male', 'female'];
signupForm: FormGroup;
forbiddenUsernames = ['Chris', 'Anna'];
ngOnInit() {
this.signupForm = new FormGroup({
'userData': new FormGroup({
this.checkForbiddenNames.bind(this)]),
'username': new FormControl(null, [Validators.required, this.checkNoBlankSpaces, this.checkForbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.required, Validators.email]),
}),
'gender': new FormControl('male'),
'hobbies': new FormArray([]),
});
}
onSubmit(): void {
console.log(this.signupForm);
}
getControls() {
return (<FormArray>this.signupForm.get('hobbies')).controls;
}
onAddHobby(): void {
const control = new FormControl(null, Validators.required);
(<FormArray>this.signupForm.get('hobbies')).push(control);
}
checkForbiddenNames(control: FormControl): { [key: string]: boolean } {
if (this.forbiddenUsernames.map(user => user.toLowerCase()).includes(control.value?.toLowerCase())) {
return {'nameIsForbidden': true};
}
}
checkNoBlankSpaces(control: FormControl): { [key: string]: boolean } {
const nonWhitespaceRegExp: RegExp = new RegExp('\\S');
if (!nonWhitespaceRegExp.test(control.value) && control.value.length > 0) {
return {'onlyWhiteSpaces': true};
}
}
usernameCustomErrorMessages(): string {
if (this.signupForm.get('userData.username').errors?.nameIsForbidden) {
return 'The given username is not available';
} else if (this.signupForm.get('userData.username').errors?.onlyWhiteSpaces) {
return 'The given username can not be blank spaces';
} else {
return 'Please type a username';
}
}
}
File: src/app/app.component.html
<div class="form-group">
<label for="username">Username</label>
<input
type="text"
id="username"
name="username"
class="form-control"
formControlName="username"
>
</div>
<span *ngIf="(signupForm.get('userData.username').invalid && signupForm.get('userData.username').touched); else usernameOk" class="help-block">
<span>{{usernameCustomErrorMessages()}}</span>
</span>
<ng-template #usernameOk><span class="help-block"> </span></ng-template>