Enrich your Angular Apps with Angular Forms

Enrich your Angular Apps with Angular Forms

In almost every Angular application you come to the point where you need information from the user. Angular Forms is a great solution for this. Angular Forms makes it possible to get rich information about the people interacting with the page and provides many possibilities with a large variety of forms. But user inputs, even in its obviously simplest form can get very complex: Fields must be validated, can have complex dependencies on each other, and should be testable. In this talk, Fabian Gosebrink will look at the complexity of Angular Forms and provide solutions that he encountered after maintaining lots of projects, web apps, and connected forms. The talk will look at the worst examples, complex validations, and the best solutions. Hopefully in your next projects, getting your user information will be easy, well testable and easy to implement.

Fb89953d3a1b1fcb862a186585c37c25?s=128

Fabian Gosebrink

September 03, 2020
Tweet

Transcript

  1. Enrich your Angular Apps with Angular Forms

  2. Why?

  3. Template Forms Reactive Forms

  4. Template Forms Reactive Forms

  5. Reactive Forms import { NgModule } from '@angular/core'; import {

    ReactiveFormsModule } from '@angular/forms @NgModule({ declarations: [...], imports: [ ReactiveFormsModule, ], providers: [], }) export class AppModule {} 1 2 3 4 5 6 7 8 9 10 11
  6. Reactive Forms import { NgModule } from '@angular/core'; import {

    ReactiveFormsModule } from '@angular/forms @NgModule({ declarations: [...], imports: [ ReactiveFormsModule, ], providers: [], }) export class AppModule {} 1 2 3 4 5 6 7 8 9 10 11 import { ReactiveFormsModule } from '@angular/forms import { NgModule } from '@angular/core'; 1 2 3 @NgModule({ 4 declarations: [...], 5 imports: [ 6 ReactiveFormsModule, 7 ], 8 providers: [], 9 }) 10 export class AppModule {} 11
  7. Reactive Forms import { NgModule } from '@angular/core'; import {

    ReactiveFormsModule } from '@angular/forms @NgModule({ declarations: [...], imports: [ ReactiveFormsModule, ], providers: [], }) export class AppModule {} 1 2 3 4 5 6 7 8 9 10 11 import { ReactiveFormsModule } from '@angular/forms import { NgModule } from '@angular/core'; 1 2 3 @NgModule({ 4 declarations: [...], 5 imports: [ 6 ReactiveFormsModule, 7 ], 8 providers: [], 9 }) 10 export class AppModule {} 11 imports: [ ReactiveFormsModule, ], import { NgModule } from '@angular/core'; 1 import { ReactiveFormsModule } from '@angular/forms 2 3 @NgModule({ 4 declarations: [...], 5 6 7 8 providers: [], 9 }) 10 export class AppModule {} 11
  8. Abstract Control

  9. abstract class AbstractControl

  10. abstract class AbstractControl @angular/forms

  11. FormControl FormGroup FormArray

  12. FormControl

  13. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: `<input [formControl]="name">`, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10
  14. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: `<input [formControl]="name">`, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10 import { FormControl } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: `<input [formControl]="name">`, 6 }) 7 export class AppComponent { 8 name = new FormControl(); 9 } 10
  15. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: `<input [formControl]="name">`, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10 import { FormControl } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: `<input [formControl]="name">`, 6 }) 7 export class AppComponent { 8 name = new FormControl(); 9 } 10 template: `<input [formControl]="name">`, import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 6 }) 7 export class AppComponent { 8 name = new FormControl(); 9 } 10
  16. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: `<input [formControl]="name">`, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10 import { FormControl } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: `<input [formControl]="name">`, 6 }) 7 export class AppComponent { 8 name = new FormControl(); 9 } 10 template: `<input [formControl]="name">`, import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 6 }) 7 export class AppComponent { 8 name = new FormControl(); 9 } 10 name = new FormControl(); import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: `<input [formControl]="name">`, 6 }) 7 export class AppComponent { 8 9 } 10
  17. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: `<input [formControl]="name">`, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10 import { FormControl } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: `<input [formControl]="name">`, 6 }) 7 export class AppComponent { 8 name = new FormControl(); 9 } 10 template: `<input [formControl]="name">`, import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 6 }) 7 export class AppComponent { 8 name = new FormControl(); 9 } 10 name = new FormControl(); import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: `<input [formControl]="name">`, 6 }) 7 export class AppComponent { 8 9 } 10 template: `<input [formControl]="name">`, name = new FormControl(); import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 6 }) 7 export class AppComponent { 8 9 } 10
  18. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <input [formControl]="name"> {{ name.status | json}} {{ name.value | json}} {{ name.errors | json}} `, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  19. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <input [formControl]="name"> {{ name.status | json}} {{ name.value | json}} {{ name.errors | json}} `, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 {{ name.status | json}} {{ name.value | json}} {{ name.errors | json}} import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <input [formControl]="name"> 7 8 9 10 `, 11 }) 12 export class AppComponent { 13 name = new FormControl(); 14 } 15
  20. FormControl import { Component } from '@angular/core'; import { FormControl

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <input [formControl]="name"> {{ name.status | json}} {{ name.value | json}} {{ name.errors | json}} `, }) export class AppComponent { name = new FormControl(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 {{ name.status | json}} {{ name.value | json}} {{ name.errors | json}} import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <input [formControl]="name"> 7 8 9 10 `, 11 }) 12 export class AppComponent { 13 name = new FormControl(); 14 } 15 {{ name.status | json}} {{ name.value | json}} {{ name.errors | json}} name = new FormControl(); import { Component } from '@angular/core'; 1 import { FormControl } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <input [formControl]="name"> 7 8 9 10 `, 11 }) 12 export class AppComponent { 13 14 } 15
  21. FormControl value: any 1 status: string 2 valid: boolean 3

    invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14
  22. FormControl value: any 1 status: string 2 valid: boolean 3

    invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 status: string value: any 1 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14
  23. FormControl value: any 1 status: string 2 valid: boolean 3

    invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 status: string value: any 1 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 valid: boolean invalid: boolean value: any 1 status: string 2 3 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14
  24. FormControl value: any 1 status: string 2 valid: boolean 3

    invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 status: string value: any 1 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 valid: boolean invalid: boolean value: any 1 status: string 2 3 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 pending: boolean disabled: boolean enabled: boolean value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 5 6 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14
  25. FormControl value: any 1 status: string 2 valid: boolean 3

    invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 status: string value: any 1 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 valid: boolean invalid: boolean value: any 1 status: string 2 3 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 pending: boolean disabled: boolean enabled: boolean value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 5 6 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 errors: ValidationErrors | null value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14
  26. FormControl value: any 1 status: string 2 valid: boolean 3

    invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 status: string value: any 1 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 valid: boolean invalid: boolean value: any 1 status: string 2 3 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 pending: boolean disabled: boolean enabled: boolean value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 5 6 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 errors: ValidationErrors | null value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 pristine: boolean dirty: boolean touched: boolean untouched: boolean value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 9 10 11 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14
  27. FormControl value: any 1 status: string 2 valid: boolean 3

    invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 status: string value: any 1 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 valid: boolean invalid: boolean value: any 1 status: string 2 3 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 pending: boolean disabled: boolean enabled: boolean value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 5 6 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 errors: ValidationErrors | null value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 pristine: boolean dirty: boolean touched: boolean untouched: boolean value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 9 10 11 12 valueChanges: Observable<any> 13 statusChanges: Observable<any> 14 valueChanges: Observable<any> statusChanges: Observable<any> value: any 1 status: string 2 valid: boolean 3 invalid: boolean 4 pending: boolean 5 disabled: boolean 6 enabled: boolean 7 errors: ValidationErrors | null 8 pristine: boolean 9 dirty: boolean 10 touched: boolean 11 untouched: boolean 12 13 14
  28. FormControl FormGroup FormArray

  29. FormControl FormGroup FormArray

  30. FormControl FormGroup FormArray

  31. FormGroup

  32. FormGroup Container for

  33. FormGroup Container for FormControls

  34. FormGroup Container for FormControls FormGroups

  35. FormGroup [Object object] { ... }

  36. import { Component } from '@angular/core'; import { FormControl, FormGroup

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup = new FormGroup({ firstName: new FormControl() }); onSubmit() { console.log(this.myFormGroup.get("firstName")) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  37. import { Component } from '@angular/core'; import { FormControl, FormGroup

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup = new FormGroup({ firstName: new FormControl() }); onSubmit() { console.log(this.myFormGroup.get("firstName")) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { FormControl, FormGroup } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21
  38. import { Component } from '@angular/core'; import { FormControl, FormGroup

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup = new FormGroup({ firstName: new FormControl() }); onSubmit() { console.log(this.myFormGroup.get("firstName")) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { FormControl, FormGroup } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21
  39. import { Component } from '@angular/core'; import { FormControl, FormGroup

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup = new FormGroup({ firstName: new FormControl() }); onSubmit() { console.log(this.myFormGroup.get("firstName")) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { FormControl, FormGroup } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 <input formControlName="firstName"> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21
  40. import { Component } from '@angular/core'; import { FormControl, FormGroup

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup = new FormGroup({ firstName: new FormControl() }); onSubmit() { console.log(this.myFormGroup.get("firstName")) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { FormControl, FormGroup } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 <input formControlName="firstName"> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 myFormGroup = new FormGroup({ firstName: new FormControl() }); import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 15 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21
  41. import { Component } from '@angular/core'; import { FormControl, FormGroup

    } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup = new FormGroup({ firstName: new FormControl() }); onSubmit() { console.log(this.myFormGroup.get("firstName")) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { FormControl, FormGroup } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 <input formControlName="firstName"> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 myFormGroup = new FormGroup({ firstName: new FormControl() }); import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 15 16 17 onSubmit() { 18 console.log(this.myFormGroup.get("firstName")) 19 } 20 } 21 onSubmit() { console.log(this.myFormGroup.get("firstName")) } import { Component } from '@angular/core'; 1 import { FormControl, FormGroup } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 myFormGroup = new FormGroup({ 14 firstName: new FormControl() 15 }); 16 17 18 19 20 } 21
  42. registerControl( addControl() removeControl() setControl()

  43. setValue() patchValue() reset()

  44. getRawValue(

  45. formGroup.getRawValue(

  46. formGroup.getRawValue( { "firstName" : "Obi Wan", "lastName" : "Kenobi" }

    1 2 3 4
  47. formGroup.value

  48. formGroup.value { "firstName" : "Obi Wan" } 1 2 3

  49. value: any status: string valid: boolean invalid: boolean pending: boolean

    disabled: boolean enabled: boolean errors: ValidationErrors | null pristine: boolean dirty: boolean touched: boolean untouched: boolean valueChanges: Observable<any> statusChanges: Observable<any>
  50. <button [disabled]="myForm.invalid"> Submit </button>

  51. <button [disabled]="myForm.invalid"> Submit </button> Also enabled in pending state!

  52. <button [disabled]="!myForm.valid"> Submit </button>

  53. <button [disabled]="!myForm.valid"> Submit </button> Only enabled when valid

  54. Demo

  55. FormBuilder

  56. FormBuilder import { Component } from '@angular/core'; import { FormControl,

    FormGroup } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup = new FormGroup({ firstName: new FormControl() }); onSubmit() { console.log(this.myFormGroup.get("firstName")) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  57. import { Component } from '@angular/core'; import { FormControl, FormGroup,

    FormBuilder } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; constructor(private fb: FormBuilder){ this.myFormGroup = fb.group({ firstName: null }); } onSubmit(){ console.log(this.myFormGroup.value) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
  58. import { Component } from '@angular/core'; import { FormControl, FormGroup,

    FormBuilder } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; constructor(private fb: FormBuilder){ this.myFormGroup = fb.group({ firstName: null }); } onSubmit(){ console.log(this.myFormGroup.value) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26
  59. import { Component } from '@angular/core'; import { FormControl, FormGroup,

    FormBuilder } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; constructor(private fb: FormBuilder){ this.myFormGroup = fb.group({ firstName: null }); } onSubmit(){ console.log(this.myFormGroup.value) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 8 9 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26
  60. import { Component } from '@angular/core'; import { FormControl, FormGroup,

    FormBuilder } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; constructor(private fb: FormBuilder){ this.myFormGroup = fb.group({ firstName: null }); } onSubmit(){ console.log(this.myFormGroup.value) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 8 9 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 constructor(private fb: FormBuilder){ import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26
  61. import { Component } from '@angular/core'; import { FormControl, FormGroup,

    FormBuilder } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; constructor(private fb: FormBuilder){ this.myFormGroup = fb.group({ firstName: null }); } onSubmit(){ console.log(this.myFormGroup.value) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 8 9 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 constructor(private fb: FormBuilder){ import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 this.myFormGroup = fb.group({ firstName: null }); import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 18 19 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26
  62. import { Component } from '@angular/core'; import { FormControl, FormGroup,

    FormBuilder } from '@angular/forms' @Component({ selector: 'my-app', template: ` <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; constructor(private fb: FormBuilder){ this.myFormGroup = fb.group({ firstName: null }); } onSubmit(){ console.log(this.myFormGroup.value) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' import { Component } from '@angular/core'; 1 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> <input formControlName="firstName"> <button>Send</button> </form> import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 7 8 9 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 constructor(private fb: FormBuilder){ import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 17 this.myFormGroup = fb.group({ 18 firstName: null 19 }); 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 this.myFormGroup = fb.group({ firstName: null }); import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 myFormGroup: FormGroup; 15 16 constructor(private fb: FormBuilder){ 17 18 19 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26 myFormGroup: FormGroup; this.myFormGroup = fb.group({ firstName: null }); import { Component } from '@angular/core'; 1 import { FormControl, FormGroup, FormBuilder } from '@angular/forms' 2 3 @Component({ 4 selector: 'my-app', 5 template: ` 6 <form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()"> 7 <input formControlName="firstName"> 8 <button>Send</button> 9 </form> 10 ` 11 }) 12 export class AppComponent { 13 14 15 16 constructor(private fb: FormBuilder){ 17 18 19 20 } 21 22 onSubmit(){ 23 console.log(this.myFormGroup.value) 24 } 25 } 26
  63. profileForm = new FormGroup({ firstName: new FormControl('') lastName: new FormControl(''),

    address: new FormGroup({ street: new FormControl(''), city: new FormControl(''), state: new FormControl(''), zip: new FormControl('') }) }); 1 2 3 4 5 6 7 8 9 10 profileForm = this.fb.group({ firstName: [''], lastName: [''], address: this.fb.group({ street: [''], city: [''], state: [''], zip: [''] }), }); 1 2 3 4 5 6 7 8 9 10
  64. Demo

  65. FormControl FormGroup FormArray

  66. FormControl FormGroup FormArray

  67. FormArray Array of Form controls

  68. FormArray Array of Form controls Dynamic controls

  69. FormArray Array of Form controls Iterating over controls Dynamic controls

  70. FormArray Array of Form controls Iterating over controls Dynamic controls

    Serialized as array
  71. FormArray import { Component } from "@angular/core"; import { FormControl,

    FormArray, FormGroup, FormBuilder } from "@angular/forms" @Component({ selector: "my-app", template: ` <form [formGroup]="myFormGroup"> <div formArrayName="myFormArray"> <input *ngFor="let control of formArray.controls; index as i" [formControlName]="i" /> </div> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; formArray: FormArray; constructor(private fb: FormBuilder) { this.formArray = fb.array([new FormControl("")]) this.myFormGroup = fb.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
  72. FormArray import { Component } from "@angular/core"; import { FormControl,

    FormArray, FormGroup, FormBuilder } from "@angular/forms" @Component({ selector: "my-app", template: ` <form [formGroup]="myFormGroup"> <div formArrayName="myFormArray"> <input *ngFor="let control of formArray.controls; index as i" [formControlName]="i" /> </div> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; formArray: FormArray; constructor(private fb: FormBuilder) { this.formArray = fb.array([new FormControl("")]) this.myFormGroup = fb.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 myFormGroup: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 17 18 19 constructor(private fb: FormBuilder) { 20 this.formArray = fb.array([new FormControl("")]) 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26
  73. FormArray import { Component } from "@angular/core"; import { FormControl,

    FormArray, FormGroup, FormBuilder } from "@angular/forms" @Component({ selector: "my-app", template: ` <form [formGroup]="myFormGroup"> <div formArrayName="myFormArray"> <input *ngFor="let control of formArray.controls; index as i" [formControlName]="i" /> </div> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; formArray: FormArray; constructor(private fb: FormBuilder) { this.formArray = fb.array([new FormControl("")]) this.myFormGroup = fb.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 myFormGroup: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 17 18 19 constructor(private fb: FormBuilder) { 20 this.formArray = fb.array([new FormControl("")]) 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26 this.formArray = fb.array([new FormControl("")]) import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 myFormGroup: FormGroup; 17 formArray: FormArray; 18 19 constructor(private fb: FormBuilder) { 20 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26
  74. FormArray import { Component } from "@angular/core"; import { FormControl,

    FormArray, FormGroup, FormBuilder } from "@angular/forms" @Component({ selector: "my-app", template: ` <form [formGroup]="myFormGroup"> <div formArrayName="myFormArray"> <input *ngFor="let control of formArray.controls; index as i" [formControlName]="i" /> </div> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; formArray: FormArray; constructor(private fb: FormBuilder) { this.formArray = fb.array([new FormControl("")]) this.myFormGroup = fb.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 myFormGroup: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 17 18 19 constructor(private fb: FormBuilder) { 20 this.formArray = fb.array([new FormControl("")]) 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26 this.formArray = fb.array([new FormControl("")]) import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 myFormGroup: FormGroup; 17 formArray: FormArray; 18 19 constructor(private fb: FormBuilder) { 20 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26 this.myFormGroup = fb.group({ myFormArray: this.formArray }); import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 myFormGroup: FormGroup; 17 formArray: FormArray; 18 19 constructor(private fb: FormBuilder) { 20 this.formArray = fb.array([new FormControl("")]) 21 22 23 24 } 25 } 26
  75. FormArray import { Component } from "@angular/core"; import { FormControl,

    FormArray, FormGroup, FormBuilder } from "@angular/forms" @Component({ selector: "my-app", template: ` <form [formGroup]="myFormGroup"> <div formArrayName="myFormArray"> <input *ngFor="let control of formArray.controls; index as i" [formControlName]="i" /> </div> <button>Send</button> </form> ` }) export class AppComponent { myFormGroup: FormGroup; formArray: FormArray; constructor(private fb: FormBuilder) { this.formArray = fb.array([new FormControl("")]) this.myFormGroup = fb.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 myFormGroup: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 17 18 19 constructor(private fb: FormBuilder) { 20 this.formArray = fb.array([new FormControl("")]) 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26 this.formArray = fb.array([new FormControl("")]) import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 myFormGroup: FormGroup; 17 formArray: FormArray; 18 19 constructor(private fb: FormBuilder) { 20 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26 this.myFormGroup = fb.group({ myFormArray: this.formArray }); import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myFormGroup"> 7 <div formArrayName="myFormArray"> 8 <input *ngFor="let control of formArray.controls; index as i" 9 [formControlName]="i" /> 10 </div> 11 <button>Send</button> 12 </form> 13 ` 14 }) 15 export class AppComponent { 16 myFormGroup: FormGroup; 17 formArray: FormArray; 18 19 constructor(private fb: FormBuilder) { 20 this.formArray = fb.array([new FormControl("")]) 21 22 23 24 } 25 } 26 <form [formGroup]="myFormGroup"> <div formArrayName="myFormArray"> <input *ngFor="let control of formArray.controls; index as i" [formControlName]="i" /> </div> <button>Send</button> </form> import { Component } from "@angular/core"; 1 import { FormControl, FormArray, FormGroup, FormBuilder } from "@angular/forms" 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 7 8 9 10 11 12 13 ` 14 }) 15 export class AppComponent { 16 myFormGroup: FormGroup; 17 formArray: FormArray; 18 19 constructor(private fb: FormBuilder) { 20 this.formArray = fb.array([new FormControl("")]) 21 this.myFormGroup = fb.group({ 22 myFormArray: this.formArray 23 }); 24 } 25 } 26
  76. Demo

  77. FormArray import { Component } from "@angular/core"; import { FormArray,

    FormBuilder } from "@angular/forms"; @Component({ selector: "my-app", template: ` <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div *ngFor="let formGroup of formArray.controls; index as i"> <my-comp [formGroup]="formGroup"></my-comp> </div> </form> ` }) export class AppComponent { myForm: FormGroup; formArray: FormArray; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.formArray = this.formBuilder.array([new FormGroup({ ... })]) this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  78. FormArray import { Component } from "@angular/core"; import { FormArray,

    FormBuilder } from "@angular/forms"; @Component({ selector: "my-app", template: ` <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div *ngFor="let formGroup of formArray.controls; index as i"> <my-comp [formGroup]="formGroup"></my-comp> </div> </form> ` }) export class AppComponent { myForm: FormGroup; formArray: FormArray; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.formArray = this.formBuilder.array([new FormGroup({ ... })]) this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 myForm: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 15 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24
  79. FormArray import { Component } from "@angular/core"; import { FormArray,

    FormBuilder } from "@angular/forms"; @Component({ selector: "my-app", template: ` <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div *ngFor="let formGroup of formArray.controls; index as i"> <my-comp [formGroup]="formGroup"></my-comp> </div> </form> ` }) export class AppComponent { myForm: FormGroup; formArray: FormArray; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.formArray = this.formBuilder.array([new FormGroup({ ... })]) this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 myForm: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 15 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24
  80. FormArray import { Component } from "@angular/core"; import { FormArray,

    FormBuilder } from "@angular/forms"; @Component({ selector: "my-app", template: ` <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div *ngFor="let formGroup of formArray.controls; index as i"> <my-comp [formGroup]="formGroup"></my-comp> </div> </form> ` }) export class AppComponent { myForm: FormGroup; formArray: FormArray; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.formArray = this.formBuilder.array([new FormGroup({ ... })]) this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 myForm: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 15 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 22 } 23 } 24
  81. FormArray import { Component } from "@angular/core"; import { FormArray,

    FormBuilder } from "@angular/forms"; @Component({ selector: "my-app", template: ` <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div *ngFor="let formGroup of formArray.controls; index as i"> <my-comp [formGroup]="formGroup"></my-comp> </div> </form> ` }) export class AppComponent { myForm: FormGroup; formArray: FormArray; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.formArray = this.formBuilder.array([new FormGroup({ ... })]) this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 myForm: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 15 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 22 } 23 } 24 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> </form> import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24
  82. FormArray import { Component } from "@angular/core"; import { FormArray,

    FormBuilder } from "@angular/forms"; @Component({ selector: "my-app", template: ` <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div *ngFor="let formGroup of formArray.controls; index as i"> <my-comp [formGroup]="formGroup"></my-comp> </div> </form> ` }) export class AppComponent { myForm: FormGroup; formArray: FormArray; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.formArray = this.formBuilder.array([new FormGroup({ ... })]) this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 myForm: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 15 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 22 } 23 } 24 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> </form> import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 <div *ngFor="let formGroup of formArray.controls; index as i"> </div> import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 8 <my-comp [formGroup]="formGroup"></my-comp> 9 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24
  83. FormArray import { Component } from "@angular/core"; import { FormArray,

    FormBuilder } from "@angular/forms"; @Component({ selector: "my-app", template: ` <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div *ngFor="let formGroup of formArray.controls; index as i"> <my-comp [formGroup]="formGroup"></my-comp> </div> </form> ` }) export class AppComponent { myForm: FormGroup; formArray: FormArray; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.formArray = this.formBuilder.array([new FormGroup({ ... })]) this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 myForm: FormGroup; formArray: FormArray; import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 15 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 22 } 23 } 24 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> </form> import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 <my-comp [formGroup]="formGroup"></my-comp> 9 </div> 10 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 <div *ngFor="let formGroup of formArray.controls; index as i"> </div> import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 8 <my-comp [formGroup]="formGroup"></my-comp> 9 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24 <my-comp [formGroup]="formGroup"></my-comp> import { Component } from "@angular/core"; 1 import { FormArray, FormBuilder } from "@angular/forms"; 2 3 @Component({ 4 selector: "my-app", 5 template: ` 6 <form [formGroup]="myForm" (ngSubmit)="onSubmit()"> 7 <div *ngFor="let formGroup of formArray.controls; index as i"> 8 9 </div> 10 </form> 11 ` 12 }) 13 export class AppComponent { 14 myForm: FormGroup; 15 formArray: FormArray; 16 17 constructor(private formBuilder: FormBuilder) {} 18 19 ngOnInit() { 20 this.formArray = this.formBuilder.array([new FormGroup({ ... })]) 21 this.myForm = this.formBuilder.group({ myFormArray: this.formArray }); 22 } 23 } 24
  84. Validation

  85. Validation import { Component, OnInit } from '@angular/core'; import {

    FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: '', lastName: '', age: '', room: null, } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  86. Validation import { Component, OnInit } from '@angular/core'; import {

    FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  87. Validation import { Component, OnInit } from '@angular/core'; import {

    FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Component, OnInit } from '@angular/core'; 1 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 constructor(private formBuilder: FormBuilder) {} 9 10 ngOnInit() { 11 this.myForm = this.formBuilder.group( 12 { 13 firstName: ['', Validators.required], 14 lastName: ['', Validators.required], 15 age: ['', Validators.required], 16 room: [null, Validators.required], 17 } 18 ); 19 } 20 } 21
  88. Validation import { Component, OnInit } from '@angular/core'; import {

    FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Component, OnInit } from '@angular/core'; 1 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 constructor(private formBuilder: FormBuilder) {} 9 10 ngOnInit() { 11 this.myForm = this.formBuilder.group( 12 { 13 firstName: ['', Validators.required], 14 lastName: ['', Validators.required], 15 age: ['', Validators.required], 16 room: [null, Validators.required], 17 } 18 ); 19 } 20 } 21 this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required], room: [null, Validators.required], } ); import { Component, OnInit } from '@angular/core'; 1 import { FormBuilder, FormGroup, Validators } from '@angular/forms'; 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 constructor(private formBuilder: FormBuilder) {} 9 10 ngOnInit() { 11 12 13 14 15 16 17 18 19 } 20 } 21
  89. Validation class Validators { static required(control: AbstractControl): ValidationErrors | null

    } 1 2 3 4 5 6 7 8 9 10 11 12 13
  90. Validation class Validators { static min(min: number): ValidatorFn static max(max:

    number): ValidatorFn static required(control: AbstractControl): ValidationErrors | null static requiredTrue(control: AbstractControl): ValidationErrors | null static email(control: AbstractControl): ValidationErrors | null static minLength(minLength: number): ValidatorFn static maxLength(maxLength: number): ValidatorFn static pattern(pattern: string | RegExp): ValidatorFn static nullValidator(control: AbstractControl): ValidationErrors | null static compose(validators: ValidatorFn[]): ValidatorFn | null static composeAsync(validators: AsyncValidatorFn[]): AsyncValidatorFn | nu } 1 2 3 4 5 6 7 8 9 10 11 12 13
  91. Validation myForm.get('controlName').errors?.min .max .required .requiredTrue .email .minLength .maxLength .pattern .nullValidator

    .compose .composeAsync 1 2 3 4 5 6 7 8 9 10 11
  92. Validation .ng-valid .ng-invalid .ng-pending .ng-pristine .ng-dirty .ng-untouched .ng-touched 1 2

    3 4 5 6 7 8 9 10 11 12 13
  93. Custom Validation

  94. Custom Validation import { AbstractControl } from '@angular/forms export class

    MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 import { AbstractControl } from '@angular/forms export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13
  95. Custom Validation import { AbstractControl } from '@angular/forms export class

    MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 import { AbstractControl } from '@angular/forms export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } import { AbstractControl } from '@angular/forms 1 2 3 4 5 6 7 8 9 10 11 12 13
  96. Custom Validation import { AbstractControl } from '@angular/forms export class

    MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 import { AbstractControl } from '@angular/forms export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } import { AbstractControl } from '@angular/forms 1 2 3 4 5 6 7 8 9 10 11 12 13 static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 5 6 7 8 9 10 11 12 } 13
  97. Custom Validation import { AbstractControl } from '@angular/forms export class

    MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 import { AbstractControl } from '@angular/forms export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } import { AbstractControl } from '@angular/forms 1 2 3 4 5 6 7 8 9 10 11 12 13 static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 5 6 7 8 9 10 11 12 } 13 static myValidator(control: AbstractControl) import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 5 if (control.value ... ) { 6 return { someProp: true }; 7 } 8 9 return null; 10 } 11 12 } 13
  98. Custom Validation import { AbstractControl } from '@angular/forms export class

    MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 import { AbstractControl } from '@angular/forms export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } import { AbstractControl } from '@angular/forms 1 2 3 4 5 6 7 8 9 10 11 12 13 static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 5 6 7 8 9 10 11 12 } 13 static myValidator(control: AbstractControl) import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 5 if (control.value ... ) { 6 return { someProp: true }; 7 } 8 9 return null; 10 } 11 12 } 13 if (control.value ... ) { return { someProp: true }; } import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 static myValidator(control: AbstractControl) 5 6 7 8 9 return null; 10 } 11 12 } 13
  99. Custom Validation import { AbstractControl } from '@angular/forms export class

    MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 import { AbstractControl } from '@angular/forms export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 export class MyCustomValidator { static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } } import { AbstractControl } from '@angular/forms 1 2 3 4 5 6 7 8 9 10 11 12 13 static myValidator(control: AbstractControl) if (control.value ... ) { return { someProp: true }; } return null; } import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 5 6 7 8 9 10 11 12 } 13 static myValidator(control: AbstractControl) import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 5 if (control.value ... ) { 6 return { someProp: true }; 7 } 8 9 return null; 10 } 11 12 } 13 if (control.value ... ) { return { someProp: true }; } import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 static myValidator(control: AbstractControl) 5 6 7 8 9 return null; 10 } 11 12 } 13 return null; import { AbstractControl } from '@angular/forms 1 2 export class MyCustomValidator { 3 4 static myValidator(control: AbstractControl) 5 if (control.value ... ) { 6 return { someProp: true }; 7 } 8 9 10 } 11 12 } 13
  100. Custom Validation import { Component, OnInit } from '@angular/core'; import

    { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  101. Custom Validation import { Component, OnInit } from '@angular/core'; import

    { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 firstName: ['', Validators.required], lastName: ['', Validators.required], age: ['', Validators.required], room: [null, Validators.required], import { Component, OnInit } from '@angular/core'; 1 import { FormBuilder, FormGroup } from '@angular/forms'; 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 constructor(private formBuilder: FormBuilder) {} 9 10 ngOnInit() { 11 this.myForm = this.formBuilder.group( 12 { 13 14 15 16 17 } 18 ); 19 } 20 } 21
  102. Custom Validation firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age:

    ['', Validators.required], room: [null, Validators.required], import { Component, OnInit } from '@angular/core'; 1 import { FormBuilder, FormGroup } from '@angular/forms'; 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 constructor(private formBuilder: FormBuilder) {} 9 10 ngOnInit() { 11 this.myForm = this.formBuilder.group( 12 { 13 14 15 16 17 } 18 ); 19 } 20 } 21
  103. Async Validation

  104. Async Validation

  105. Async Validation import { AbstractControl } from '@angular/forms'; export class

    MyCustomValidator { static myAsyncValidator(control: AbstractContro : Observable<any> { // ... } } 1 2 3 4 5 6 7 8 9 10 import { AbstractControl } from '@angular/forms'; export class MyCustomValidator { static myAsyncValidator(control: AbstractContro : Observable<any> { // ... } } 1 2 3 4 5 6 7 8 9 10
  106. Async Validation import { AbstractControl } from '@angular/forms'; export class

    MyCustomValidator { static myAsyncValidator(control: AbstractContro : Observable<any> { // ... } } 1 2 3 4 5 6 7 8 9 10 import { AbstractControl } from '@angular/forms'; export class MyCustomValidator { static myAsyncValidator(control: AbstractContro : Observable<any> { // ... } } 1 2 3 4 5 6 7 8 9 10 static myAsyncValidator(control: AbstractContro : Observable<any> { import { AbstractControl } from '@angular/forms'; 1 2 export class MyCustomValidator { 3 4 5 6 // ... 7 } 8 9 } 10
  107. Async Validation import { Component, OnInit } from '@angular/core'; import

    { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  108. Async Validation import { Component, OnInit } from '@angular/core'; import

    { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age: ['', Validators.required], room: [null, Validators.required], } import { Component, OnInit } from '@angular/core'; 1 import { FormBuilder, FormGroup } from '@angular/forms'; 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 rooms: Room[] = [ /* ... */ ]; 9 10 constructor(private formBuilder: FormBuilder) {} 11 12 ngOnInit() { 13 14 15 16 17 18 19 20 ); 21 } 22 } 23
  109. Async Validation import { Component, OnInit } from '@angular/core'; import

    { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required], [MyCustomValidator.myAsyncValidat age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  110. Async Validation import { Component, OnInit } from '@angular/core'; import

    { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required], [MyCustomValidator.myAsyncValidat age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required], [MyCustomValidator.myAsyncValidat age: ['', Validators.required], room: [null, Validators.required], } import { Component, OnInit } from '@angular/core'; 1 import { FormBuilder, FormGroup } from '@angular/forms'; 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 rooms: Room[] = [ /* ... */ ]; 9 10 constructor(private formBuilder: FormBuilder) {} 11 12 ngOnInit() { 13 14 15 16 17 18 19 20 ); 21 } 22 } 23
  111. Cross Field Validation

  112. Cross Field Validation import { Component, OnInit } from '@angular/core';

    import { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  113. Cross Field Validation import { Component, OnInit } from '@angular/core';

    import { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age: ['', Validators.required], room: [null, Validators.required], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 lastName: ['', [Validators.required, MyCustomValidator.myValidator]] import { Component, OnInit } from '@angular/core'; 1 import { FormBuilder, FormGroup } from '@angular/forms'; 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 rooms: Room[] = [ /* ... */ ]; 9 10 constructor(private formBuilder: FormBuilder) {} 11 12 ngOnInit() { 13 this.myForm = this.formBuilder.group( 14 { 15 firstName: ['', Validators.required], 16 17 age: ['', Validators.required], 18 room: [null, Validators.required], 19 } 20 ); 21 } 22 } 23
  114. Cross Field Validation import { Component, OnInit } from '@angular/core';

    import { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age: ['', Validators.required], room: [null, Validators.required], }, { validators: [...], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
  115. Cross Field Validation import { Component, OnInit } from '@angular/core';

    import { FormBuilder, FormGroup } from '@angular/forms'; import { Room } from './room'; @Component({ /* ... */ }) export class FormComponent implements OnInit { myForm: FormGroup; rooms: Room[] = [ /* ... */ ]; constructor(private formBuilder: FormBuilder) {} ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ['', Validators.required], lastName: ['', [Validators.required, MyCustomValidator.myValidator]] age: ['', Validators.required], room: [null, Validators.required], }, { validators: [...], } ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { validators: [...], } import { Component, OnInit } from '@angular/core'; 1 import { FormBuilder, FormGroup } from '@angular/forms'; 2 import { Room } from './room'; 3 4 @Component({ /* ... */ }) 5 export class FormComponent implements OnInit { 6 myForm: FormGroup; 7 8 rooms: Room[] = [ /* ... */ ]; 9 10 constructor(private formBuilder: FormBuilder) {} 11 12 ngOnInit() { 13 this.myForm = this.formBuilder.group( 14 { 15 firstName: ['', Validators.required], 16 lastName: ['', [Validators.required, MyCustomValidator.myValidator]] 17 age: ['', Validators.required], 18 room: [null, Validators.required], 19 }, 20 21 22 23 ); 24 } 25 } 26
  116. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    export class MyFormValidator { static formValidator(/* ... */): ValidatorFn { return (formGroup: FormGroup) => { // return null if everything is okay // otherwise an object }; } } 1 2 3 4 5 6 7 8 9 10
  117. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    export class MyFormValidator { static formValidator(/* ... */): ValidatorFn { return (formGroup: FormGroup) => { // return null if everything is okay // otherwise an object }; } } 1 2 3 4 5 6 7 8 9 10 export class MyFormValidator { } import { FormGroup, ValidatorFn } from '@angular/forms' 1 2 3 static formValidator(/* ... */): ValidatorFn { 4 return (formGroup: FormGroup) => { 5 // return null if everything is okay 6 // otherwise an object 7 }; 8 } 9 10
  118. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    export class MyFormValidator { static formValidator(/* ... */): ValidatorFn { return (formGroup: FormGroup) => { // return null if everything is okay // otherwise an object }; } } 1 2 3 4 5 6 7 8 9 10 export class MyFormValidator { } import { FormGroup, ValidatorFn } from '@angular/forms' 1 2 3 static formValidator(/* ... */): ValidatorFn { 4 return (formGroup: FormGroup) => { 5 // return null if everything is okay 6 // otherwise an object 7 }; 8 } 9 10 static formValidator(/* ... */): ValidatorFn { } import { FormGroup, ValidatorFn } from '@angular/forms' 1 2 export class MyFormValidator { 3 4 return (formGroup: FormGroup) => { 5 // return null if everything is okay 6 // otherwise an object 7 }; 8 9 } 10
  119. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    export class MyFormValidator { static formValidator(/* ... */): ValidatorFn { return (formGroup: FormGroup) => { // return null if everything is okay // otherwise an object }; } } 1 2 3 4 5 6 7 8 9 10 export class MyFormValidator { } import { FormGroup, ValidatorFn } from '@angular/forms' 1 2 3 static formValidator(/* ... */): ValidatorFn { 4 return (formGroup: FormGroup) => { 5 // return null if everything is okay 6 // otherwise an object 7 }; 8 } 9 10 static formValidator(/* ... */): ValidatorFn { } import { FormGroup, ValidatorFn } from '@angular/forms' 1 2 export class MyFormValidator { 3 4 return (formGroup: FormGroup) => { 5 // return null if everything is okay 6 // otherwise an object 7 }; 8 9 } 10 return (formGroup: FormGroup) => { }; import { FormGroup, ValidatorFn } from '@angular/forms' 1 2 export class MyFormValidator { 3 static formValidator(/* ... */): ValidatorFn { 4 5 // return null if everything is okay 6 // otherwise an object 7 8 } 9 } 10
  120. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    export class MyFormValidator { static formValidator(value: any): ValidatorFn { return (formGroup: FormGroup) => { // return null if everything is okay // otherwise an object }; } } 1 2 3 4 5 6 7 8 9 10
  121. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    export class MyFormValidator { static formValidator(value: any): ValidatorFn { return (formGroup: FormGroup) => { // return null if everything is okay // otherwise an object }; } } 1 2 3 4 5 6 7 8 9 10 static formValidator(value: any): ValidatorFn { import { FormGroup, ValidatorFn } from '@angular/forms' 1 2 export class MyFormValidator { 3 4 return (formGroup: FormGroup) => { 5 // return null if everything is okay 6 // otherwise an object 7 }; 8 } 9 } 10
  122. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    import { Room } from './room'; export class MyFormValidator { static formValidator(value: any): ValidatorFn { return (formGroup: FormGroup) => { const control1 = formGroup.get('control1Name'); const control2 = formGroup.get('control2Name'); if(/* ... */) { // ... } return null; }; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
  123. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    import { Room } from './room'; export class MyFormValidator { static formValidator(value: any): ValidatorFn { return (formGroup: FormGroup) => { const control1 = formGroup.get('control1Name'); const control2 = formGroup.get('control2Name'); if(/* ... */) { // ... } return null; }; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const control1 = formGroup.get('control1Name'); const control2 = formGroup.get('control2Name'); import { FormGroup, ValidatorFn } from '@angular/forms' 1 import { Room } from './room'; 2 3 export class MyFormValidator { 4 static formValidator(value: any): ValidatorFn { 5 return (formGroup: FormGroup) => { 6 7 8 9 if(/* ... */) { 10 // ... 11 } 12 13 return null; 14 }; 15 } 16 } 17
  124. Cross Field Validation import { FormGroup, ValidatorFn } from '@angular/forms'

    import { Room } from './room'; export class MyFormValidator { static formValidator(value: any): ValidatorFn { return (formGroup: FormGroup) => { const control1 = formGroup.get('control1Name'); const control2 = formGroup.get('control2Name'); if(/* ... */) { // ... } return null; }; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const control1 = formGroup.get('control1Name'); const control2 = formGroup.get('control2Name'); import { FormGroup, ValidatorFn } from '@angular/forms' 1 import { Room } from './room'; 2 3 export class MyFormValidator { 4 static formValidator(value: any): ValidatorFn { 5 return (formGroup: FormGroup) => { 6 7 8 9 if(/* ... */) { 10 // ... 11 } 12 13 return null; 14 }; 15 } 16 } 17 if(/* ... */) { // ... } return null; import { FormGroup, ValidatorFn } from '@angular/forms' 1 import { Room } from './room'; 2 3 export class MyFormValidator { 4 static formValidator(value: any): ValidatorFn { 5 return (formGroup: FormGroup) => { 6 const control1 = formGroup.get('control1Name'); 7 const control2 = formGroup.get('control2Name'); 8 9 10 11 12 13 14 }; 15 } 16 } 17
  125. Demo

  126. Testing

  127. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  128. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('MyValidator', () => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  129. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('MyValidator', () => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 4 5 6 7 8 9 10 11 12 13 }); 14
  130. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('MyValidator', () => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 4 5 6 7 8 9 10 11 12 13 }); 14 it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 6 7 8 9 10 11 12 }); 13 }); 14
  131. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('MyValidator', () => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 4 5 6 7 8 9 10 11 12 13 }); 14 it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 6 7 8 9 10 11 12 }); 13 }); 14 const formControl = new FormControl(''); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 7 formControl.value = ''; 8 const result = MyCustomValidator.myValidator(formContr 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14
  132. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('MyValidator', () => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 4 5 6 7 8 9 10 11 12 13 }); 14 it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 6 7 8 9 10 11 12 }); 13 }); 14 const formControl = new FormControl(''); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 7 formControl.value = ''; 8 const result = MyCustomValidator.myValidator(formContr 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14 formControl.value = ''; import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 const formControl = new FormControl(''); 7 8 const result = MyCustomValidator.myValidator(formContr 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14
  133. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('MyValidator', () => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 4 5 6 7 8 9 10 11 12 13 }); 14 it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 6 7 8 9 10 11 12 }); 13 }); 14 const formControl = new FormControl(''); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 7 formControl.value = ''; 8 const result = MyCustomValidator.myValidator(formContr 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14 formControl.value = ''; import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 const formControl = new FormControl(''); 7 8 const result = MyCustomValidator.myValidator(formContr 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14 const result = MyCustomValidator.myValidator(formContr import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 const formControl = new FormControl(''); 7 formControl.value = ''; 8 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14
  134. Testing import { FormControl, ValidatorFn } from '@angular/forms'; describe('MyValidator', ()

    => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('MyValidator', () => { describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 describe('should return valid if', () => { it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 4 5 6 7 8 9 10 11 12 13 }); 14 it('value is empty', () => { const formControl = new FormControl(''); formControl.value = ''; const result = MyCustomValidator.myValidator(formContr expect(result.ageNotValid).toBe(true); }); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 6 7 8 9 10 11 12 }); 13 }); 14 const formControl = new FormControl(''); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 7 formControl.value = ''; 8 const result = MyCustomValidator.myValidator(formContr 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14 formControl.value = ''; import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 const formControl = new FormControl(''); 7 8 const result = MyCustomValidator.myValidator(formContr 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14 const result = MyCustomValidator.myValidator(formContr import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 const formControl = new FormControl(''); 7 formControl.value = ''; 8 9 expect(result.ageNotValid).toBe(true); 10 }); 11 12 }); 13 }); 14 expect(result.ageNotValid).toBe(true); import { FormControl, ValidatorFn } from '@angular/forms'; 1 2 describe('MyValidator', () => { 3 describe('should return valid if', () => { 4 5 it('value is empty', () => { 6 const formControl = new FormControl(''); 7 formControl.value = ''; 8 const result = MyCustomValidator.myValidator(formContr 9 10 }); 11 12 }); 13 }); 14
  135. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  136. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 21 const formGroup = new FormGroup({ 22
  137. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20
  138. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 9 10 11 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 21
  139. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 9 10 11 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const result = validatorFn(formGroup); 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 21 const formGroup = new FormGroup({ 22 age: new FormControl(20), 23 room: new FormControl({ text: 'room 2', value: 'room-2' }), 24 }); 25
  140. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 9 10 11 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const result = validatorFn(formGroup); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 expect(result).not.toEqual(null); describe( restricts age correctly , () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 21 const formGroup = new FormGroup({ 22 age: new FormControl(20), 23 room: new FormControl({ text: 'room 2', value: 'room-2' }), 24 }); 25 26 const result validatorFn(formGroup); 27
  141. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 9 10 11 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const result = validatorFn(formGroup); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 expect(result).not.toEqual(null); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); const formGroup = new FormGroup({ age: new FormControl(20), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).toEqual(null); }); }); ({ , }), }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 }); 32
  142. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 9 10 11 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const result = validatorFn(formGroup); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 expect(result).not.toEqual(null); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 19 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 20 21 const formGroup = new FormGroup({ 22 age: new FormControl(20), 23 room: new FormControl({ text: 'room 2', value: 'room-2' }), 24 }); 25 26 const result = validatorFn(formGroup); 27 28 expect(result).toEqual(null); 29 }); 30
  143. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 9 10 11 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const result = validatorFn(formGroup); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 expect(result).not.toEqual(null); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 19 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 20 const formGroup = new FormGroup({ age: new FormControl(20), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); ({ , }), }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 21 22 23 24 25 26 const result = validatorFn(formGroup); 27 28 expect(result).toEqual(null); 29 }); 30 }); 31 }); 32
  144. Testing import { FormControl, FormGroup } from '@angular/forms'; import {

    RestrictAgeValidator } from './restrict-age.validator'; describe('RestrictAgeValidator', () => { describe('restricts age correctly', () => { it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 it('should not return null when given age is under the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); const result = validatorFn(formGroup); expect(result).not.toEqual(null); }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const formGroup = new FormGroup({ age: new FormControl(9), room: new FormControl({ text: 'room 2', value: 'room-2' }), }); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 9 10 11 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const result = validatorFn(formGroup); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 expect(result).not.toEqual(null); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 it('should return null when given age is above the required age', () => { const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 19 20 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 20 import { FormControl, FormGroup } from '@angular/forms'; 1 import { RestrictAgeValidator } from './restrict-age.validator'; 2 3 describe('RestrictAgeValidator', () => { 4 describe('restricts age correctly', () => { 5 it('should not return null when given age is under the required age', () => { 6 const validatorFn = RestrictAgeValidator.restrictAgeValidator(10); 7 8 const formGroup = new FormGroup({ 9 age: new FormControl(9), 10 room: new FormControl({ text: 'room 2', value: 'room-2' }), 11 }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 const result = validatorFn(formGroup); expect(result).toEqual(null); ({ , }), }); 12 13 const result = validatorFn(formGroup); 14 15 expect(result).not.toEqual(null); 16 }); 17 18 it('should return null when given age is above the required age', () => { 19 const validatorFn = RestrictAgeValidator.restrictAgeValidator(18); 20 21 const formGroup = new FormGroup({ 22 age: new FormControl(20), 23 room: new FormControl({ text: 'room 2', value: 'room-2' }), 24 }); 25 26 27 28 29 }); 30 }); 31 }); 32
  145. ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ..., lastName: ...,

    ... }, { ... } ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ValueChanges
  146. ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ..., lastName: ...,

    ... }, { ... } ); this.myForm.valueChanges.subscribe(console.log); this.myForm.get('firstName').valueChanges.subscribe(console.lo } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ValueChanges
  147. ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ..., lastName: ...,

    ... }, { ... } ); this.myForm.valueChanges.subscribe(console.log); this.myForm.get('firstName').valueChanges.subscribe(console.lo } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 this.myForm.valueChanges.subscribe(console.log); ngOnInit() { 1 this.myForm = this.formBuilder.group( 2 { 3 firstName: ..., 4 lastName: ..., 5 ... 6 }, 7 { 8 ... 9 } 10 ); 11 12 13 this.myForm.get('firstName').valueChanges.subscribe(console.lo 14 } 15 ValueChanges
  148. ngOnInit() { this.myForm = this.formBuilder.group( { firstName: ..., lastName: ...,

    ... }, { ... } ); this.myForm.valueChanges.subscribe(console.log); this.myForm.get('firstName').valueChanges.subscribe(console.lo } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 this.myForm.valueChanges.subscribe(console.log); ngOnInit() { 1 this.myForm = this.formBuilder.group( 2 { 3 firstName: ..., 4 lastName: ..., 5 ... 6 }, 7 { 8 ... 9 } 10 ); 11 12 13 this.myForm.get('firstName').valueChanges.subscribe(console.lo 14 } 15 this.myForm.get('firstName').valueChanges.subscribe(console.lo ngOnInit() { 1 this.myForm = this.formBuilder.group( 2 { 3 firstName: ..., 4 lastName: ..., 5 ... 6 }, 7 { 8 ... 9 } 10 ); 11 12 this.myForm.valueChanges.subscribe(console.log); 13 14 } 15 ValueChanges
  149. Custom Form Controls

  150. Custom Form Controls <form [formGroup]="myForm"> <!-- ... --> <app-block-buttons formControlName="toggle"></app-block-buttons>

    <!-- ... --> </form> 1 2 3 4 5
  151. Control Value Accessor

  152. Control Value Accessor import { Component } from '@angular/core'; import

    { ControlValueAccessor } from '@angular/forms'; @Component({ /* ... */ }) export class MyComponent implements ControlValueAccessor { writeValue(obj: any): void { // ... } registerOnChange(fn: any): void { // ... } registerOnTouched(fn: any): void { // ... } setDisabledState?(isDisabled: boolean): void { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  153. Control Value Accessor import { Component } from '@angular/core'; import

    { ControlValueAccessor } from '@angular/forms'; @Component({ selector: 'app-my-component', templateUrl: './my.component.html', styleUrls: ['./my.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyComponent), multi: true, }, ], }) export class MyComponent implements ControlValueAccessor { //... } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  154. Control Value Accessor import { Component } from '@angular/core'; import

    { ControlValueAccessor } from '@angular/forms'; @Component({ selector: 'app-my-component', templateUrl: './my.component.html', styleUrls: ['./my.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyComponent), multi: true, }, ], }) export class MyComponent implements ControlValueAccessor { //... } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyComponent), multi: true, }, ], import { Component } from '@angular/core'; 1 import { ControlValueAccessor } from '@angular/forms'; 2 3 @Component({ 4 selector: 'app-my-component', 5 templateUrl: './my.component.html', 6 styleUrls: ['./my.component.scss'], 7 8 9 10 11 12 13 14 }) 15 export class MyComponent implements ControlValueAccessor { 16 17 //... 18 19 } 20
  155. Recap FormGroup vs FormControl vs FormArray FormBuilder Validation Testing ValueChanges

    (rich API) Custom Form Controls
  156. None
  157. Stay safe!