In Angular 2, how do I set up an asynchronous validator when using template driven forms?

I have 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 the template, I applied it like this:

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

      

Then I applied validation messages from code (not template) as described in Angular 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()

it is not called when the validator's promise is resolved, so the confirmation message for username

does not appear. However, if you try to edit the field name

. What should I do to initiate an update in the user interface?

Here is the plunker for my code.


Literature:

+3


source to share


1 answer


You can subscribe to an event statusChanges

that fires after the asynchronous validator is called

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

      



Modified Plunker

+2


source







All Articles