-1

The question may look kind of confusing but let's say I have a button like following:

<button type="button" class="menu-button" [disabled]="isInvalidForm()">Save</button

isInvalidForm() {
console.log('I am running!');
return this.nameValidator.errors || this.lastnameValidator.errors;
}

And when it is like this (I just simplified the form for the sake of the question) , it logs 100s of 'I am running!' as it is called that much. Even though when I click around the form, it is called another 100 times..

I doubt that this way of checking the button is enabled or not does not look good at all.. One other way is triggering the function on the button click but that is definitely not what I want. What would be the best to avoid tons of calls to that function to disable a simple button? (or is it really OK to use function in DOM elements? )

or in short, is it the exact same thing using:

<button type="button" class="menu-button" [disabled]="isInvalidForm()">Save</button>

with:

  <button type="button" class="menu-button" [disabled]="nameValidator.errors || lastnameValidator.errors">Save</button>
curiousBoy
  • 6,334
  • 5
  • 48
  • 56
  • "best" how? The code you have doesn't do much of anything, so who cares if it gets called thousands of times? Are you paying by function call or something? ;) – Heretic Monkey Oct 07 '19 at 21:04
  • @HereticMonkey - It just made feel that Im doing something wrong as it is called a lot. Yeah it is not doing much, but I do care. I dont want it to be called if it is unnecessary and if there is better way to do it. Thanks for your feedback – curiousBoy Oct 07 '19 at 21:11

1 Answers1

2
<button type="button" class="menu-button" [disabled]="!form.valid">Save</button

"Every time the value of a form control changes, Angular runs validation and generates either a list of validation errors, which results in an INVALID status, or null, which results in a VALID status." Official Angular Documentation

Using form.invalid might enable the button until async validations are finished.

Korbinian Kuhn
  • 726
  • 4
  • 9
  • thanks but my point is, is it the exact same thing using a function which also just returns !form.valid ? – curiousBoy Oct 07 '19 at 21:14
  • 1
    To my knowledge, this is the common way to disable forms. The calls to your function and your logging is just the change detection of angular. I don't think wrapping from.valid with a function or a direct binding makes a difference for the change detection. – Korbinian Kuhn Oct 07 '19 at 21:22
  • 1
    @curiousBoy, the advantage of use form.valid it's that you can choose when the "check" is done: -on change, on blur or on submit. Using,e.g. `{updateOn: 'blur'}` you check only on blur, see https://angular.io/api/forms/AbstractControlOptions – Eliseo Oct 08 '19 at 06:50
  • @Eliseo finally!!! That is the answer I was looking for. Thanks a lot. So I can technically reduce the number of the callback by limiting it to some specific event, rather than every cycle loop. Do you see any performance impact with these call backs tho? as long as it just check form validator error (even though there are 10,20 whatever form controls), would it eventually create human recognizable impact on performance? – curiousBoy Oct 08 '19 at 21:45
  • 1
    I looked up the source of [AbstractFormControl](https://github.com/angular/angular/blob/master/packages/forms/src/model.ts) and the validation state is stored as a string. form.valid just returns a string comparison against this variable ```this.status === 'VALID'```. The validation only runs on form changes, not on every template change detection. In FormGroups/FormArrays only the changed control and its parent status are validated and not all controls of the form. As long as your validators are not long running (e.g. http request), there shouldn't be a human recognizable delay. – Korbinian Kuhn Oct 09 '19 at 20:00
  • Edit: The comparison is against a constant so even faster ```this.status === VALID``` – Korbinian Kuhn Oct 09 '19 at 21:09