У меня есть собственный валидатор FormGroup, который неправильно обновляет состояние ошибки валидатора после возврата из вызова веб-службы, который проверяет, используется ли уже displayName.
В приведенном ниже коде я знаю, что мой html-код работает, потому что функция validateDisplayName моего компонента отображает «Отображаемое имя уже используется», когда ввод displayName пуст. Затем, когда вы начинаете вводить буквы, вызывается веб-служба, чтобы начать проверку записи в третьей букве, а затем сообщение исчезает. Когда я набираю отображаемое имя, которое соответствует единице в БД, веб-служба правильно возвращает true, но return { displayNameTaken: true }; вызов не приводит к отображению ошибки.
Я знаю, что это как-то связано с обещанием, которое возвращает веб-служба, но я не могу найти решение.
компонент.ts
ngOnInit() {
this.dnFormGroup = this.formBuilder.group({
displayName: ['', this.validateDisplayName.bind(this)]
});
}
public validateDisplayName(control: AbstractControl): any {
console.info("RegisterComponent validateDisplayName - ENTRY");
if (control.value.length >= 3) {
return this.authService.validateDisplayName(control.value).then(
(res) => {
console.info("RegisterComponent validateDisplayName - res: " +res);
if (res) {
console.info("RegisterComponent validateDisplayName - displayName already used");
return { displayNameTaken: true };
} else {
console.info("RegisterComponent validateDisplayName - - displayName can be used");
return null;
}
},
(err) => {
console.info("RegisterComponent validateDisplayName - err: " +err);
return { displayNameTaken: true };
});
}
console.info("RegisterComponent validateDisplayName - ############## EXIT");
return { displayNameTaken: true };
}
компонент-service.ts
public validateDisplayName(displayName: string) {
console.info("AuthService validateDisplayName - displayName: " +displayName);
return this.http
.get(environment.server_url +"profile_cont/displaynameexists/" +displayName +"/")
.toPromise()
.then(
(response) => {
const existsBool = response.json();
console.info("AuthService validateDisplayName - existsBool: " +existsBool);
return existsBool;
},
(error) => {
console.info("AuthService validateDisplayName - error: " +error);
return true;
});
}
компонент.html
<form [formGroup] = "dnFormGroup">
<fieldset>
<div class = "row">
<section class = "col col-6">
<label class = "input">
<i class = "icon-append fa fa-user"></i>
<input formControlName = "displayName" type = "text" minlength = "3" maxlength = "10" placeholder = "Display name">
<b class = "tooltip tooltip-top-right"> <i class = "fa fa-user txt-color-teal"></i> Please provide a 3 to 10 char name for site display purposes.</b>
</label>
<div *ngIf = "dnFormGroup.get('displayName').hasError && dnFormGroup.get('displayName').hasError('displayNameTaken')">
Display Name is already used
</div>
</section>
</div>
</fieldset>
</form>
Спасибо, Боб



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ансинхронный валидатор должен быть третьим аргументом, попробуйте:
this.dnFormGroup = this.formBuilder.group({
displayName: ['', null, this.validateDisplayName.bind(this)]
});
@BobC не уверен, почему у вас возникла ошибка Cannot read property 'get' of undefined при указании null для второго аргумента. Я поиграл с подобным примером, и указание как [Validators.required], так и null не дает никаких ошибок. Вот стекблиц: асинхронный валидатор
Я понимаю что ты имеешь ввиду. Между нашим кодом нет большой разницы. Я использую Angular 5.2.6 под Angular CLI 6.2.1. Я не мог определить, какой угловой статический блиц запущен. Ошибка повторяется.
Добавление null не работает, как и добавление пустых кавычек. Оба вызывают ошибку
ERROR TypeError: Cannot read property 'get' of undefined. Вы снова заставили меня взглянуть на API — см. ссылка на сайт. Я думал, что второй вариант в конструкторе необязателен, но ошибся. Вот мое исправление:displayName: ['', [Validators.required], this.validateDisplayName.bind(this)]Теперь все работает отлично. Спасибо!