Maximum value validator with dynamic value

Miguelopezv picture Miguelopezv · Aug 30, 2017 · Viewed 6.9k times · Source

I have a service which returns a value representing the money user has, and I want the user to be able to do transactions for a value equal or less than the total amount of money. I've tried to use max validation like this:

valid() {
        const form: FormGroup = this._fb.group({
          fond: ['', [Validators.required]],
          serie: ['', [Validators.required]],
          account: ['', [Validators.required, Validators.min(1)]],
          value: ['', [Validators.required, Validators.min(1)]],
          subAccount: ['', [Validators.required, Validators.min(1)]]
        });
        return form;
      }

But it won't work, it seems like the value in max() has to be set from the beginning, so it will just assume totalAmount as undefined.

Answer

Harry Ninh picture Harry Ninh · Aug 30, 2017

Update for your edited question:

Use this:

value: ['', [
  Validators.required, 
  Validators.min(1), 
  (control: AbstractControl) => Validators.max(this.totalAmount)(control)
]]

You can achieve that by using this syntax:

(control: AbstractControl) => Validators.max(this.totalAmount)(control)

Why?

  • When you supply Validators.max(this.totalAmount), it creates a validation function with the given parameter (current value of this.totalAmount) then assign it to the form control.
  • When you use fat arrow function, what is assigned to the form control is the fat arrow definition itself. Everytime the fat arrow function is invoked (during validity checking), it revaluates the Validators.max(this.totalAmount) and create new validation function with the current value of this.totalAmount, thus makes it dynamic.