8

I have this FormGroup

defaultIdNumberValidator = [Validators.required, Validators.minLength(6),
    Validators.maxLength(11)];

this.registerForm = this.formBuilder.group({ 
  permissions: this.formBuilder.group({
    country: ['', [Validators.required]],
    identityNumber: [null, this.defaultIdNumberValidator],
  }, {validator: [this.validateId]}) 
});

and I want to clear and add validators to identityNumber depending on some conditions in this.validateId method.

validateId(input: AbstractControl) {
  if(condition) {
    input.get("identityNumber").clearValidators(); //this is working
  }
  if(condition) {
    input.get("identityNumber").setValidators(this.defaultIdNumberValidator); //not working
  }
}

When setValidators method is called I get this error (line :109 is line where setValidators is called)

ERROR TypeError: Cannot read property 'defaultIdNumberValidator' of undefined
    at RegisterComponent.validateId (register.component.ts:109)
    at eval (forms.js:742)
    at Array.map (<anonymous>)
    at _executeValidators (forms.js:742)
    at eval (forms.js:694)
    at eval (forms.js:742)
    at Array.map (<anonymous>)
    at _executeValidators (forms.js:742)
    at eval (forms.js:694)
    at eval (forms.js:742)

UPDATE:

I restart development server and now i get this error

ERROR TypeError: Cannot read property 'setValidators' of undefined
at RegisterComponent.validateId (register.component.ts:109)
at eval (forms.js:742)
at Array.map (<anonymous>)
at _executeValidators (forms.js:742)
at eval (forms.js:694)
at eval (forms.js:742)
at Array.map (<anonymous>)
at _executeValidators (forms.js:742)
at eval (forms.js:694)

UPDATE 2:

I create simple plunker to reproduce error. If you first click input and than click somewhere else you get error under it. So this error should be removed when length of input value is >= 2, and should be visible again when is >= 5. I also don't know why error disappear when length of input value is 3 and not 2...

4
  • Can you create a plunkr? Does your validateId method sit in a separate ts file? Commented Dec 18, 2017 at 11:45
  • You are obviously losing the reference to 'this' somewhere Commented Dec 18, 2017 at 11:46
  • See update. I will try create a plunkr Commented Dec 18, 2017 at 12:59
  • I create plunker. See update 2. Commented Dec 18, 2017 at 14:52

1 Answer 1

11

You need to bind(this) to keep the context of this. Also you need to use updateValueAndValidity for the change of the validators to be updated. There we also need to not emit an event, if you were, this would case looping until your browser crashes. So change the following:

}, {validator: this.validateId.bind(this)}) 

and the validator would look like this:

validateId(input: AbstractControl) {
  // ...
  if(...) {
    input.get("identityNumber").clearValidators();
    input.get("identityNumber").updateValueAndValidity({emitEvent:false, onlySelf:true});
  }
  if(...) {
    input.get("identityNumber").setValidators(this.defaultIdNumberValidator);
    input.get("identityNumber").updateValueAndValidity({emitEvent:false, onlySelf:true});
  }
}

Your PLUNKER

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.