Here's the StackBlitz showing the problem.
I have a reactive form with an Email field and Send Verification Code button. When the code is sent, the Verification Code field appears, so the user can type in the code and it will be validated immediately. If the code is invalid, the Verification Code field must be marked as invalid. But this doesn't seem to work using signal.
Here's the verification code in the form template:
<mat-form-field appearance="fill" id="veriCodeFld">
<mat-label>Verification Code</mat-label>
<input
autocomplete="off"
formControlName="code"
matInput
placeholder="Code from email"
required
type="text"
/>
@if(isTouchedAndInvalid('code') || (!store.emailVerified() &&
store.veriCodeIsWrong())) {
<mat-error>{{ getErrorMessage("code") }}</mat-error>
} @if (store.emailVerified() && this.codeCrl?.valid) {
<mat-icon matSuffix>check</mat-icon>
} @else if (!store.emailVerified() && store.veriCodeIsWrong()) {
<mat-icon matSuffix>error</mat-icon>
}
</mat-form-field>
The custom validator:
export function verificationCodeValidator(
veriCodeIsWrongSignal: Signal<boolean>
): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
return veriCodeIsWrongSignal() ? { verificationCodeInvalid: true } : null;
};
}
And the way it's applied to the field:
frm = this.fb.group({
email: [
'',
[Validators.email, Validators.required],
null,
{ updateOn: 'blur' },
],
code: [
'',
[
Validators.required,
Validators.minLength(6),
verificationCodeValidator(this.store.veriCodeIsWrong),
],
null,
],
});
The validation is performed when the user types in the code (from the form code):
constructor() {
this.validationMessages = this.initValidationMessages();
this.frm
.get('code')!
.valueChanges.pipe(
debounceTime(400),
distinctUntilChanged(),
takeUntilDestroyed()
)
.subscribe((value) => this.validateCode(value));
}
How can I make it work?