Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Custom Form Validators losing access to `this` in class

I'm building an Angular 2 application (2.0) and I've got a form that makes use of the ReactiveForms module. As such, I'm using validator functions on the input fields, including custom validators. This works fine.

My issue is that I am also trying to use a custom AsyncValidator on a form field. It seems straight forward enough, but I can never reference properties inside the class from within the AsyncValidator method.

The FormGroup and the FormControl properties for the form itself and the input field look like this in the component's class:

form: FormGroup;
userName = new FormControl("", [Validators.required], [this.userNameAsyncValidator]);

There's also a FormBuilder in the ngOnInit() function that attaches the form to the form property.

constructor(private fb: FormBuilder, // this.fb comes from here
          private css: ClientSecurityService) { // this.css comes from here
}

ngOnInit() {
  this.form = this.fb.group({
      "userName": this.userName
    }
  );
}

My issue is that in the AsyncValidator, I am unable to reference any of the services I've defined in the component's class - including this.css. Here's the validator:

userNameAsyncValidator(control: FormControl): {[key: string]: any} {
  return new Promise(resolve => {
    this.css.getUrl()
      .subscribe(
        data => {
          console.log('Returned http data:', data);
          resolve(null);
        },
        err => {
          // Log errors if any
          console.log(err);
        });
  });
}

No matter what I do, this.css in the userNameAsyncValidator() call is undefined.

(I realize that my validator doesn't actually do anything - I just want to be able to call my ClientSecurity service so that I can, eventually, call a remote HTTP webservice to get a response as to whether the userName being entered is valid and not already in use.)

like image 876
Michael Oryl Avatar asked Oct 31 '16 17:10

Michael Oryl


People also ask

What is dirty in angular form?

When the user changes the value in the watched field, the control is marked as "dirty" When the user blurs the form control element, the control is marked as "touched"

How do you validate a reactive form?

Reactive forms include a set of validator functions for common use cases. These functions receive a control to validate against and return an error object or a null value based on the validation check. Import the Validators class from the @angular/forms package. In the ProfileEditor component, add the Validators.

Is it possible to define validators in form builder?

FormBuilder allows us to explicitly declare forms in our components. This allows us to also explicitly list each form control's validators. In our example we are going to build a small form with three inputs, user name, email and profile description. We will start with looking at our app.

How will you add validators in FormControl?

We can add Validators dynamically using the SetValidators or SetAsyncValidators. This method is available to FormControl, FormGroup & FormArray. There are many use cases where it is required to add/remove validators dynamically to a FormControl or FormGroup.


1 Answers

Your validator is not being called with your component as this. Notice that you are passing a loose reference to this.userNameAsyncValidator You can bind your validator without worrying about this conflicts because angular validation doesn't rely on this

userName = new FormControl("", [
    Validators.required
], [
    this.userNameAsyncValidator.bind(this)
]);
like image 52
Juan Mendes Avatar answered Oct 06 '22 02:10

Juan Mendes