Результат веб-службы валидатора Angular 5 FormGroup не вызывает ngIF hasError

У меня есть собственный валидатор 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>

Спасибо, Боб

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ансинхронный валидатор должен быть третьим аргументом, попробуйте:

this.dnFormGroup = this.formBuilder.group({
    displayName: ['', null, this.validateDisplayName.bind(this)]
});

Добавление null не работает, как и добавление пустых кавычек. Оба вызывают ошибку ERROR TypeError: Cannot read property 'get' of undefined. Вы снова заставили меня взглянуть на API — см. ссылка на сайт. Я думал, что второй вариант в конструкторе необязателен, но ошибся. Вот мое исправление: displayName: ['', [Validators.required], this.validateDisplayName.bind(this)] Теперь все работает отлично. Спасибо!

BobC 19.02.2019 21:19

@BobC не уверен, почему у вас возникла ошибка Cannot read property 'get' of undefined при указании null для второго аргумента. Я поиграл с подобным примером, и указание как [Validators.required], так и null не дает никаких ошибок. Вот стекблиц: асинхронный валидатор

Vadi 20.02.2019 10:06

Я понимаю что ты имеешь ввиду. Между нашим кодом нет большой разницы. Я использую Angular 5.2.6 под Angular CLI 6.2.1. Я не мог определить, какой угловой статический блиц запущен. Ошибка повторяется.

BobC 21.02.2019 09:39

Другие вопросы по теме