I have a Redux-SPA with a Messaging System with mailboxes (basically just folders). When the user wants to create a new mailbox (folder), a dialog gets shown where the user can enter a new mailbox name. To prevent unnecessary API calls, I look into the state to see if the mailbox/folder does already exist. If yes, I want to invalidate the form and disable the "Create" button.
I have already made sure that the function returns the correct values via the tap()
. The control is invalidated correctly if it is empty, so the default validator works correctly. Just my custom validator is not working somehow.
Where is my error? What can I try to debug further?
This is my code:
@Component({
selector: 'app-new-mailbox-dialog',
templateUrl: 'new-mailbox-dialog.component.html',
})
export class NewMailboxDialogComponent implements OnInit {
formControl: FormControl = new FormControl('', [Validators.required], this.mailboxNameExists.bind(this));
constructor(
public dialogRef: MatDialogRef<NewMailboxDialogComponent>,
private messagingFacade: MessagingFacade
) {}
ngOnInit() {}
onNoClick(): void {
this.dialogRef.close();
}
mailboxNameExists(control: FormControl): Observable<ValidationErrors | null> {
return this.messagingFacade.getMailboxesList$.pipe(
tap(() => console.log(control.value)),
map(names => names.find(mailbox => mailbox.designation === control.value)),
map(exists => exists ? { mailboxNameExists: true } : null)
tap(value => console.log(value)),
);
}
}
CodePudding user response:
I usually write my AsyncValidatorFn streams/method as follows:
validator(): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
if (!control.value || control.pristine) {
return of(null);
}
return control.valueChanges.pipe(
debounceTime(300),
distinctUntilChanged(),
take(1),
switchMap(value => {
return this.messagingFacade.getMailboxesList$;
}),
catchError(err => of(null)),
map(response => {
return response ? { error: true } : null;
}),
finalize(() => {
control.markAsTouched();
this.ref.markForCheck();
})
);
};
}
Not sure you need the finalize, I have this usually do to the detection strat.
Also in the template, which you do not show I am normally checking for touched and invalid along with the errors to show the error message.
CodePudding user response:
you can try using the of
method
MessagingFacade TS:
getMailboxesList$ = of([{designation: 'test'}])