How Remove custom Validators with method RemoveValidators

462 Views Asked by At

I have a question how can I remove my custom validators in the easiest/best way? I know that since angular 12 there is a method RemoveValidators, it is based on the reference of a given validator, that is, it is not easy to remove it.

What is the best way to remove such validators with parameters ?

Below i added stackblitz with non working sample: https://stackblitz.com/edit/base-angular-12-app-arm6g6?file=src/app/app.component.ts

3

There are 3 best solutions below

0
IDK4real On BEST ANSWER

The reason your code fails is because you are incorrectly passing the reference to your method.

Every time you call AppComponent.forbiddenNameValidator(/admin|test|abc/) you return a new anonymous function.

In your code, you are calling it twice, first in line 25 and then in line 37. Each of the calls generates a new anonymous function which has its own reference. You can prove this by simply doing the following test:

const first = AppComponent.forbiddenNameValidator(/admin|test|abc/);
const second = AppComponent.forbiddenNameValidator(/admin|test|abc/);

console.log(first === second) // false

Then, how do we fix this?

According to the Official Documentation, you need to store the return value of the validator in a const or property.

This stackblitz contains a link with this approach. Notice that the return of the validator is being stored in a property:

forbiddenNameValidator = ForbiddenNameValidator(/admin|test|abc/);f

This property is then passed in validators array and in the removeValidators method. Also note that I added the call to the updateValueAndValidity() of the form after removing the validator.

This is because according to the documentation, you should always call the updateValueAndValidity() of the form whose validators where altered.

0
spots On

You need to provide the instance of the validator to remove it.

export class AppComponent implements OnInit {
  name = 'Custom Validator Angular ' + VERSION.major;
  form: FormGroup;
  constructor(private fb: FormBuilder) {}

  static forbiddenNameValidator(regex: RegExp) {
    return ForbiddenNameValidator(regex);
  }

  //Create an instance of the validator
  myCustomValidatorInstance =
    AppComponent.forbiddenNameValidator(/admin|test|abc/);

  ngOnInit() {
    this.form = this.fb.group({
      FirstName: [
        '',
        [
          Validators.required,
          Validators.minLength(3),
          this.myCustomValidatorInstance,  //add the instance of the validator
        ],
      ],
    });
  }
  get firstname() {
    return this.form.controls['FirstName'];
  }

  removeCustomValidator() {
    //provide the same instance of the validator to remove it
    this.form.get('FirstName').removeValidators(this.myCustomValidatorInstance);
  }
}

Here's an updated version of your stackblitz.

0
Amir BenAmara On

you need store the result of the validator in a property and then pass that property in the validators array and removeValidators method. After calling the removeValidators method, and also call the updateValueAndValidity() method to update the form control.

import { Component } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { ForbiddenNameValidator } from './forbidden-name.directive';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = new FormControl('', [Validators.required, this.forbiddenNameValidator]);

  forbiddenNameValidator = ForbiddenNameValidator(/admin|test|abc/);

  removeValidator() {
    this.name.removeValidators(this.forbiddenNameValidator);
    this.name.updateValueAndValidity();
  }

}