Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maximum value validator with dynamic value

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.

like image 497
miguelopezv Avatar asked Aug 30 '17 05:08

miguelopezv


People also ask

How do I add custom validators dynamically in reactive form?

We can add Validators dynamically using the SetValidators or SetAsyncValidators. This method is available to FormControl, FormGroup & FormArray. There are many use cases where it is required to add/remove validators dynamically to a FormControl or FormGroup.

What is dynamic validation?

In ASP.NET 3.5 a DynamicValidator was added. It basically "Enforces and catches exceptions that are thrown in a data model and displays the error."

What are custom validators?

Building a custom validator In it's simplest form, a validator is really just a function that takes a Control and returns either null when it's valid, or and error object if it's not.


2 Answers

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.
like image 155
Harry Ninh Avatar answered Oct 15 '22 19:10

Harry Ninh


Just a little addition to the previous answers, when you need to set the value of the validator of a formControl of another formControl of the same form, you can init the form without validators, and register them after, just like this:

const form: FormGroup = this._fb.group({
      from: [''],
      to: ['']
});

form.controls.from.setValidators([
    Validators.required,
    (control: AbstractControl) => Validators.max(this.form.controls.to.value)(control)
]);

And the same goes for to.

like image 20
Kiss Koppány Avatar answered Oct 15 '22 18:10

Kiss Koppány