Need to manually (and programmatically) mark a form field as invalid in your Angular Material app?

If so, then be happy. I'll show you how to do it here.

But Why Would You Want to Do It?

You might be thinking to yourself: "The Anguar framework is pretty good at detecting errors all by itself. Why would anyone need to manually mark a field invalid?"

One reason is when it comes to complex validations. Sometimes you have fields with values that are only valid if certain other fields have a specific value.

Angular might have trouble validating those fields by its lonesome.

Or maybe you're doing some kind of asynchronous validation and, for whatever reason, you're not in a position to do the usual thing with a method that returns Observable<ValidationErrors | null>. In that case, you'll need to manually mark a field as invalid.

You keep doing stuff with Angular long enough and you'll find other reasons. I'm sure.

That's the why. Now let's get into the how.

Reminder: This Is for Angular Material

You probably read the title but just in case you missed it: this solution is for Angular Material. I haven't tested it with anything else.

So if you're going with Bootstrap or some proprietary UI solution, it might not work for you.

Keep that in mind.

Touch One Another

That subhead is from an old Yoko Ono tweet: "Touch one another."

Well that's what you need to do to mark a field as invalid. Just touch it.

And if the user hasn't done anything to it, then it's automagically invalid.

So let's take a look at how to do that.

Suppose I've got a FormGroup object in my code called basicInfoFormGroup. It's used to input basic information about a contact in a CRM app.

Now let's say that I want to mark the firstName field as invalid right out of the gate. That would generally be a user-hostile thing to do, but here I'm testing a solution.

  ngOnInit() {
    this.basicInfoFormGroup.controls['firstName'].markAsTouched();
  }

That'll do it.

Yep. The markAsTouched() method is what makes the magic happen here. It tells the framework to assume the underlying field has been touched by the user. 

And once that field has been touched, the framework does the validation logic for you.

If the user hasn't done anything yet, then it's marked invalid.

Just keep in mind: if you mark the field as touched and there's valid input in there, it won't get marked invalid.

But you probably don't want it to get marked invalid in that situation. So you're good.

If You're Still Not Happy

Another route you can take, and one that should work without Angular Material, is this:

this.basicInfoFormGroup.controls['firstName'].setErrors({'incorrect': true});

That will also get the job done.

But in that situation, no matter what the user entered (even if it's valid), you'll set the field to invalid.

If you want to remove all errors, just go this route:

this.basicInfoFormGroup.controls['firstName'].setErrors(null);

Then you're back to Square One.

Wrapping It Up

There you have it. A couple of great ways to manually set form fields to an invalid status.

Copy and paste the code you see here and put it in your own source. Then, tweak it a bit so that it works with your business requirements.

Have fun!