Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular2 custom template validator has stale values

I am stuck for a while now with the following problem. I am implementing an angular 2 custom validator that simply checks if a number is within a range. Used like this, everything works fine:

<input type="text" id="doseSimple" class="form-control"
       required 
       name="doseSimple" 
       [(ngModel)]="doseSimple"
       #doseControl ="ngModel"
       validateRange
       from="2"
       to="20"
       >

<div *ngIf="doseControl.errors && (doseControl.dirty || doseControl.touched)">
   <span *ngIf="doseControl.errors.tooSmall">Too small</span>
   <span *ngIf="doseControl.errors.tooBig">Too big</span>
</div> 

In my case, the validation is a bit more complex. There is a dropdown. The from and to values depend on the selection of the dropdown. There is just an event attached to the dropdown that sets doseFrom doseTo properties:

  <input type="text" id="name" class="form-control"
         required 
         name="doseComplex" 
         [(ngModel)]="doseComplex"
         #doseComplexControl ="ngModel"
         validateRange
         [from]="doseFrom"
         [to]="doseTo"
         >
  <div *ngIf="doseComplexControl.errors && (doseComplexControl.dirty || doseComplexControl.touched)">
     <span *ngIf="doseComplexControl.errors.tooSmall">Too small</span>
     <span *ngIf="doseComplexControl.errors.tooBig">Too big</span>
  </div> 

The validator validates the value, but with from and to from the selection before. The values of from and to are like a step behind. How to fix that?

I created a plunker to show the problem: https://plnkr.co/edit/C0sbL8pRwsZcEZ5r1ODY?p=preview

like image 575
yonexbat Avatar asked Sep 26 '26 03:09

yonexbat


1 Answers

I would implement registerOnValidatorChange method to do it working:

export class RangeValidator implements Validator {
  @Input()
  get from() {
    return this._from;
  }
  set from(value: number) {
    this._from = value;
    if (this._onChange) this._onChange();
  }

  @Input()
  get to() {
    return this._to;
  }
  set to(value: number) {
    this._to = value;
    if (this._onChange) this._onChange();
  }

  validate(c: FormControl): { [key: string]: boolean; } {
    ...
  }

  private _from: number;

  private _to: number;

  private _onChange: () => void;

  registerOnValidatorChange(fn: () => void): void { 
    this._onChange = fn; 
  }
}

Modified Plunker

And you can delete updateValueAndValidity

See also angular source code

  • https://github.com/angular/angular/blob/4.0.0-rc.5/packages/forms/src/directives/validators.ts#L67-L90
like image 124
yurzui Avatar answered Sep 27 '26 19:09

yurzui



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!