Angular makes working with forms a blast, but it also promotes one unfortunate form behaviour that is not the most user friendly. Thankfully it is also really easy to fix. Let’s see what is the issue, shall we?

1. The problem:

The thirst thing I have learnt when building Angular forms is that I can track their validation states very easily:

So I’ve quickly implemented my first form and ended up with something like the one you can see in the screenshot below:

What is wrong with this picture?

It shows the initial state of the form — right after a user navigates into the view… full of validation errors.

We can’t have our forms screaming errors at users when they haven’t even started interacting with them, right?

2. The (imperfect) typical solution:

So I thought: Ooh, now I know what these other form controls properties that Angular gives us are for! Let’s use .dirty or .touched state to only display fields’ validations when user interacted with them:

After adding `.dirty` state check the form is slightly better…

Let’s try this out:

This behaviour seems to be better — initially, when the form loads, the user sees no errors and only after he started interacting with a field the message will appear.

Still, there is one last problem, and that’s the one many developers miss:

⬅️ the submit button.

A very simple and common solution in Angular forms is to make the button disabled based on the form’s validity:

<button [disabled]="formRef.invalid"></button>

When you make the submit button disabled and there are no errors displayed, users won’t know why they can’t click the button!

Sure, with small forms it’s easy to figure out. But take a more complex one, possibly with some data preloaded, where usually not all fields are required… it can stop being obvious for the user what specifically is wrong when the only indication is the submit button’s state.

3. The final solution:

So in the olden days, in the “classic” web applications, servers were often the only places for validation logic. Nothing on the frontend was preventing user form submitting the form to the backend, and the backend would return a page will all validation messages that described which fields were missing.

Now, I’m not advocating that we should remove the frontend validation — having an instant feedback instead of doing a roundtrip to a server is definitely a great thing. So what’s solution we’ll strive for?