Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactive Form name unique validator

Tags:

angular

I'm doing a web application in Angular 6 and I'm using Reactive Form. I have a name field that I want to validate if it's unique or not. I'm comparing its value with an array.

companies: Company[];

this.companyFormGroup = this.fb.group({
      name: [null, Validators.required],
      emailAddress: [null, Validators.compose([Validators.required, Validators.email])]
    }, {validator: this.uniqueValidator});

uniqueValidator(control: AbstractControl) {
    const name = control.get('name').value;

    if (control.get('name').valid) {
      const isNameUnique = this.companies.map(company => company.name).some(value => value === name);

      if (!isNameUnique) {
        console.log(isNameUnique);
        control.get('name').setErrors({unavailable: true});
      }
    }
  }

Cannot read property 'companies' of undefined at push../src/app/modules/create-company/create-company.component.ts.CreateCompanyComponent.uniqueValidator (create-company.component.ts:79) at forms.js:602 at Array.map () at _executeValidators (forms.js:602) at FormGroup.validator (forms.js:567)

My goal is to present an error if the name that the user has entered already exists and remove the error if the name is unique.

like image 910
RRGT19 Avatar asked Sep 20 '25 01:09

RRGT19


1 Answers

the context in your validator method when called from within the FormControl/FormBuilder is not referencing your current component. This is the reason why this will be undefined.

You fix this by using bind to bind this to the validator in order to set the context:

validator: this.uniqueValidator.bind(this)

You can test it by printing this before and after the applying of bind:

uniqueValidator(control: AbstractControl) {
    const name = control.get('name').value;
    console.log(this)
     /*
    if (control.get('name').valid) {
      const isNameUnique = this.companies.map(company => company.name).some(value => value === name);

      if (!isNameUnique) {
        console.log(isNameUnique);
        control.get('name').setErrors({unavailable: true});
      }
    }*/
  }
like image 59
wentjun Avatar answered Sep 22 '25 04:09

wentjun