3

I've defined a directive for my asynchronous validator:

@Directive({
  selector: '[validatorUsername]',
  providers: [{ provide: NG_ASYNC_VALIDATORS, useExisting: ValidatorUsernameDirective, multi: true }]
})
export class ValidatorUsernameDirective implements Validator {
  validate(c: AbstractControl) {
    let username = c.value;

    return new Promise(resolve => {
      setTimeout(() => {
        if( username === "nemo" ) {
          resolve({
            'taken': true
          })
        } else {
          resolve(null);
        }
      }, 1000);
    });
  }
}

In template, I've applied it as follows:

<input type="text" [(ngModel)]="username" name="username" required validatorUsername>

Then I've applied validation messages from code (not from template), as described in Angular's Cookbook, chapter Form Validation:

export class App implements OnInit {
  @ViewChild('myForm') myForm: NgForm;

  name: string;
  username: string;

  ngOnInit() {
    this.myForm.valueChanges.subscribe(_ => this.onValueChanged());
  }

  onValueChanged() {
    // fill 'formErrors' object
  }

  formErrors = {
    'name': '',
    'username': ''
  };
}

The problem is that onValueChanged() doesn't get called when validator's promise is resolved, thus the validation message for username does not appear. It appears though if you try to edit the name field. What should I do to trigger the update on UI?

Here is the plunker for my code.


References:

Community
  • 1
  • 1
turdus-merula
  • 8,546
  • 8
  • 38
  • 50

1 Answers1

2

You can subscribe to statusChanges event that is fired after calling async validator

this.myForm.statusChanges.subscribe(_=> this.onValueChanged());

Modified Plunker

yurzui
  • 205,937
  • 32
  • 433
  • 399