title: How to properly implement nested forms with Validator and Control Value Accessor?
body: <p>In my application, I have a need for a reusable nested form component, such as <strong>Address</strong>. I want my <code>AddressComponent</code> to deal with its own FormGroup, so that I don't need to pass it from the outside. 
  At Angular conference (<a href="https://youtu.be/CD_t3m2WMM8?t=1522" rel="noreferrer">video</a>, <a href="https://docs.google.com/presentation/d/e/2PACX-1vTS20UdnMGqA3ecrv7ww_7CDKQM8VgdH2tbHl94aXgEsYQ2cyjq62ydU3e3ZF_BaQ64kMyQa0INe2oI/pub?slide=id.g293d7d2b9d_1_1532" rel="noreferrer">presentation</a>) Kara Erikson, a member of Angular Core team recommended to implement <code>ControlValueAccessor</code> for the nested forms, making the nested form effectively just a <code>FormControl</code>. </p>
  
  <p>I also figured out that I need to implement <code>Validator</code>, so that the validity of my nested form can be seen by the main form. </p>
  
  <p>In the end, I created the SubForm class that the nested form needs to extend: </p>
  
  <pre><code>export abstract class SubForm implements ControlValueAccessor, Validator {
  
    form: FormGroup;
  
    public onTouched(): void {
    }
  
    public writeValue(value: any): void {
      if (value) {
        this.form.patchValue(value, {emitEvent: false});
        this.onTouched();
      }
    }
  
    public registerOnChange(fn: (x: any) =&gt; void): void {
      this.form.valueChanges.subscribe(fn);
    }
  
    public registerOnTouched(fn: any): void {
      this.onTouched = fn;
    }
  
    setDisabledState(isDisabled: boolean): void {
      isDisabled ? this.form.disable()
        : this.form.enable();
    }
  
    validate(c: AbstractControl): ValidationErrors | null {
      return this.form.valid ? null : {subformerror: 'Problems in subform!'};
    }
  
    registerOnValidatorChange(fn: () =&gt; void): void {
      this.form.statusChanges.subscribe(fn);
    }
  }
  </code></pre>
  
  <p>If you want your component to be used as a nested form, you need to do the following: </p>
  
  <pre><code>@Component({
    selector: 'app-address',
    templateUrl: './address.component.html',
    styleUrls: ['./address.component.css'],
    providers: [
      {
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() =&gt; AddressComponent),
        multi: true
      },
      {
        provide: NG_VALIDATORS,
        useExisting: forwardRef(() =&gt; AddressComponent),
        multi: true
      }
    ],
  })
  
  export class AddressComponent extends SubForm {
  
    constructor(private fb: FormBuilder) {
      super();
      this.form = this.fb.group({
        street: this.fb.control('', Validators.required),
        city: this.fb.control('', Validators.required)
      });
    }
  
  }
  </code></pre>
  
  <p>Everything works well unless I check the validity status of my subform from the template of my main form. In this case <code>ExpressionChangedAfterItHasBeenCheckedError</code> is produced, see <code>ngIf</code> statement (<a href="https://stackblitz.com/edit/github-3q4znr?file=src%2Fapp%2Fupper%2Fupper.component.html" rel="noreferrer">stackblitz code</a>) : </p>
  
  <pre><code>&lt;form action=""
        [formGroup]="form"
        class="main-form"&gt;
    &lt;h4&gt;Upper form&lt;/h4&gt;
    &lt;label&gt;First name&lt;/label&gt;
    &lt;input type="text"
           formControlName="firstName"&gt;
           &lt;div *ngIf="form.controls['address'].valid"&gt;Hi&lt;/div&gt; 
    &lt;app-address formControlName="address"&gt;&lt;/app-address&gt;
    &lt;p&gt;Form:&lt;/p&gt;
    &lt;pre&gt;{{form.value|json}}&lt;/pre&gt;
    &lt;p&gt;Validity&lt;/p&gt;
    &lt;pre&gt;{{form.valid|json}}&lt;/pre&gt;
  
  
  &lt;/form&gt;
  </code></pre>