Angular Form Control Validation Patterns
Tags: angular, typescript, formcontrols
Published: 2020-05-14 19:14:49


Note: Since writing this article, we no longer recommend explicit FormGroup or FormControl use. 
[See theses articles instead](
https://dev.to/jwp/angular-validation-using-ngmodel-55gf)


Angular's built-in Form Validation engine saves a ton of time when writing your own form validators. 

It's simple to understand and works well.  But we as developers have to think about things a little differently. 

**What's a FormGroup?**
```html
<form [formGroup]="formGroup">
```
A [formGroup](https://angular.io/api/forms/FormGroupDirective) is an Angular directive.

The code above is assigning "formGroup"  to the [formGroup] directive. This is called 'a binding'.

>
<Sup>
Note: The form element doesn't have to exist in the HTML it can just be created in our code.


FormGroup bindings are indirect bindings to the elements. Traditional Angular bindings are direct element bindings.

**A FormGroup Aggregates FormControls**

```typescript
<form [formGroup]="formGroup"> 
<div class="Info" *ngIf="person.isEdit">
 <label>First Name</label>
   <input formControlName="firstName" 
    id="personFirstName"
    placeholder="Enter First Name here"
    type ="text">
</div>
...
```
The input element above, has a formControlName. It is assigned the name "firstName" which will be contained in the *formGroup* in our code. 
><Sup>
Notice; however, that there is no direct binding to a "Person" object done here. It's done in the Javascript code. The formControl also uses indirect binding techniques.

**The Typescript Bindings**

The new formGroup must be created at ngInit time as show below.  This is where we see the actual property bindings to the person object.

```typescript 
private formGroupBind() { 
  let namePattern = 
  /^(?=.{1,40}$)[a-zA-Z]+(?:[-'\s][a-zA-Z]+)*$/;      
  this.formGroup = new FormGroup({
  // The lastName key is the Form control Name                            
  lastName: new FormControl(
  //Property binding 
  this.person.lastName, [
  //One of more actions to perform
   Validators.required,
  Validators.pattern(namePattern),
]),
... repeat pattern above for all formcontrols
this.formGroup.enable;
}

// The person class 
export class Person {   
 firstName: string = "";
 lastName: string = "";
 middleName: string = "";
...
```
Each FormControl is an object, where the key is used in the HTML. It Binds that partiular element with that particular formControl.

The heart of the indirection is that the key of the formControl is used as the formControlName, and the specif person field is bound here.

Quite different from traditional binding. 


```typescript
// Instead of a name for this element, we assign a formControlName
<input formControlName="firstName"  
```
Each formControl can specify one or more validation rules like this:
```typescript
firstName: new FormControl(
  this.person.firstName, [
            
   Validators.required,
   Validators.pattern(
      namePattern),
  ]),
```
Here we are saying that the firstName formControl requires validation and the pattern is a regex statement in the variable namePattern.

```typescript
 // using a regex pattern, this is the validation of the content
 let namePattern = 
/^(?=.{1,40}$)[a-zA-Z]+(?:[-'\s][a-zA-Z]+)*$/;
```

**/^(?=.{1,40}$)[a-zA-Z]+(?:[-'\s][a-zA-Z]+)*$/;**
- ^ start a first of the line
- (?=.{1,40}$) Non Capture Group of any char from 1 to 40 chars in length
-[a-zA-Z]+ These characters are allowed, one or more matches
-(?:[-'\s][a-zA-Z]+) Non Capture Group, can have other characters followed by alphabet. 1 or more times
-* any other context
-$ up to end of line

When the user inputs invalid values, Angular will mark that element's background color to a red tint. It stays that way until it's correct. Before we save anything we  check the validity via the 
formGroup.isValid property

**Thinking Differently**

When we decide to use FormControls we need to use that interface to get/set values and determine validation.  We don't usually set values at the DOM layer any longer, and we don't rely on NGModel; as all the binding is done with the [FormControlGroup](https://www.google.com/search?q=form+control+group) (the container of all the formControls).

Here's an example of checking all formControls within a formGroup for validity.

```typescript
if(formGroup.Valid){
  //save to back end...
}
```

[FormControls](https://angular.io/api/forms/FormControl), are too nice to ignore when validation is a primary concern.

JWP2020