Component code-
ngOnInit(): void {
this.form = this.fb.group({
currentPassword: ['', [Validators.required], [this.matchCurrentPassword]],
newPassword: ['', [Validators.required, Validators.minLength(6), Validators.maxLength(12)]],
confirmPassword: ['', [Validators.required]]
}
, { validator: this.ConfirmedValidator('newPassword', 'confirmPassword') }
)
}
matchCurrentPassword = (
control: AbstractControl
): Observable<ValidationErrors | ValidationErrors> => {
return this.userService.matchCurrentPassword(localStorage.getItem("userId"), control.value)
.pipe
(tap(x => { console.log("response:", x) }),
(map((x: any) => { return x.isExecute ? { matches: true } : { matches: false }; }))
)
}
ConfirmedValidator(controlName: string, matchingControlName: string) {
return (formGroup: FormGroup) => {
const control = formGroup.controls[controlName];
const matchingControl = formGroup.controls[matchingControlName];
if (matchingControl.errors && !matchingControl.errors.confirmedValidator) {
return;
}
if (control.value !== matchingControl.value) {
matchingControl.setErrors({ confirmedValidator: true });
} else {
matchingControl.setErrors(null);
}
}
}
Html code-
<mat-form-field appearance="outline" fxFlex="1 1 calc(100% - 10px)"fxFlex.lt-md="1 1 calc(100% - 10px)" fxFlex.lt-sm="100%" fxFlex.xs="100%" class="from-color">
<mat-label class="label-padding">Enter Current Password</mat-label>
<input type="password" class="label-padding" type="text" style="-webkit-text-security: disc;"matInput placeholder="Current Password" formControlName="currentPassword" />
<mat-error *ngIf="currentPassword.errors?.required && currentPassword.touched">Enter current password</mat-error>
<mat-error *ngIf="currentPassword.errors?.matches==false">Doesn't match</mat-error>
</mat-form-field>
The validation for matching current password works perfectly & shows error message according to the condition. But its input field remains invalid after that.
I've also tried validating rest of the input fields. But the currentPassword remains invalid & that causes the entire form remaining invalid.
Why is this happening & how to solve this? Does anyone have any idea?
According to Defining custom validators,
That function takes an Angular control object and returns either null if the control value is valid or a validation error object.
You need to return null
for matchCurrentPassword
function if the validation is valid.
And return { matches: true }
in matchCurrentPassword
function when the validation is failed.
.component.ts
matchCurrentPassword = (
control: AbstractControl
): Observable<ValidationErrors | null> => {
let userId = localStorage.getItem('userId');
return this.userService.matchCurrentPassword(userId, control.value).pipe(
tap(x => {
console.log('response:', x);
}),
map((x: any) => {
return x.isExecute ? null : { matches: true };
})
);
};
.component.html
<mat-error *ngIf="currentPassword.errors?.matches">Doesn't match</mat-error>