When and how to validate forms in AngularJS?

Tomek Sułkowski
frontend.coach
Published in
3 min readMar 14, 2016

Form validation in Angular is pretty straightforward, right? You just use validation directives to apply some rules and ngMessage module’s directives to display the errors. Let’s see how it’d look like:

And this is probably how most of us start to write it. But then we run the app and see this:

Wait. We certainly don’t want to display errors to our users right after they load up the form. Ok, but we do have a simple fix for that — just add ng-show to have a better control over when we want to display the messages, like this:

<ng-messages for="aForm.aField.$error"
ng-show="aForm.aField.$invalid && aForm.aField.$dirty">

That’s better — the error starts to appear only when user interacts with the — but I still don’t like the fact from the very first letter of the e-mail address he’s trying to type he’s being screamed at him by the form that this is not a valid e-mail. “Well, I know it’s not a correct address, I’ve just started typing, man!”

We could add the ng-model-options=”{updateOn: ‘blur’}” to make it a bit better, but it has it’s own downsides, so for now let’s leave it as it is and move on to the next problem.

What is almost too easy to do when working with forms in Angular is to disable the submit button if the field is not valid. Just add ng-disabled=”aForm.$invalid” and you’re all set, right?

In a case of some simple forms, that’s probably ok. But imagine we have many more fields, not all of them needs to be interacted with, but then again some of them has to… User fills in what he think is enough and points his mouse on to the submit button. But it’s disabled. Why is it disabled? Well, there probably is some required field that he missed. But we don’t show any errors unless the field is interacted with, remember?

What we want to have here is a possibility of user clicking the submit button and if there are any errors that are not yet displayed, they should be at this moment, otherwise the form should submit.

Therefore we will refrain from setting the ng-disabled directive and create a custom directive instead. We’ll call it “submit-if-valid” and implement the desired functionality inside:

And that’s it!

Now in your forms all you need to do is change the submit button’s ng-click attribute to our new directive, like so:

<button submit-if-valid="save()">Send</button>

And this is the form in action:

You can try it out for yourself in this jsbin:
http://jsbin.com/jakufa/edit?html,js,output

What are your thoughts on this way of handling form validation in Angular? Do you have any alternative solutions? Don’t hesitate to comment!

Also, I’ll be sharing here more useful bits and pieces like this so you’re more than welcome to follow my profile.

--

--