title: Angular child component and validation message
body: <p>I've got the following child component with a form and I need to display error message under my control when parent component submit main form.</p>
  
  <pre><code>import {
    Component, ChangeDetectorRef, forwardRef,
    NgModule, OnInit
  } from '@angular/core';
  import {
    FormGroup, FormControl, FormBuilder, Validators,
    NG_VALIDATORS, Validator, AbstractControl, ValidationErrors
  } from '@angular/forms';
  import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
  import { CommonModule } from '@angular/common';
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
  
  export const ADDRESS_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() =&gt; AddressFormComponent),
    multi: true
  };
  
  export const ADDRESS_VALIDATORS: any = {
    provide: NG_VALIDATORS,
    useExisting: forwardRef(() =&gt; AddressFormComponent),
    multi: true
  };
  
  @Component({
    selector: 'app-address-form',
    templateUrl: 'address-form.component.html',
    providers: [ADDRESS_VALUE_ACCESSOR, ADDRESS_VALIDATORS],
  })
  export class AddressFormComponent implements OnInit, ControlValueAccessor, Validator {
  
    addressForm: FormGroup;
  
    private innerValue: any;
  
    onModelTouched: Function = () =&gt; { };
    onModelChange: Function = () =&gt; { };
  
    constructor(
      private _fb: FormBuilder,
      private ref: ChangeDetectorRef,
  
    ) { }
  
    ngOnInit() {
  
      this.addressForm = this._fb.group({
        'via': new FormControl('', Validators.required),
        'civico': new FormControl(''),
        'cap': new FormControl(''),
        'comune': new FormControl(''),
        'provincia': new FormControl(''),
        'regione': new FormControl(''),
        'stato': new FormControl(''),
        'frazione': new FormControl('')
      });
  
    }
  
    // get accessor
    get value(): any {
      return this.innerValue;
    }
  
    // set accessor including call the onchange callback
    set value(v: any) {
      if (v !== this.innerValue) {
        this.innerValue = v;
        this.onModelChange();
      }
    }
  
    // Set touched on blur
    onBlur() {
      this.onModelTouched();
    }
  
    writeValue(value: any): void {
      this.value = value;
  
      if (this.value != null) {
        this.addressForm.get('via').setValue(this.value.via);
        this.addressForm.get('civico').setValue(this.value.civico);
        this.addressForm.get('cap').setValue(this.value.cap);
        this.addressForm.get('comune').setValue(this.value.comune);
        this.addressForm.get('provincia').setValue(this.value.provincia);
        this.addressForm.get('frazione').setValue(this.value.frazione);
        this.addressForm.get('stato').setValue(this.value.stato);
        this.addressForm.get('regione').setValue(this.value.regione);
      }
  
      this.ref.markForCheck();
    }
  
    registerOnChange(fn: Function): void {
  
      this.addressForm.valueChanges.subscribe(() =&gt; {
        fn(this.addressForm.value);
      });
  
      this.onModelChange = fn;
    }
  
    registerOnTouched(fn: Function): void {
      this.onModelTouched = fn;
    }
  
    validate(c: AbstractControl): ValidationErrors | null {
      return this.addressForm.valid ? null : { subformerror: 'Problems in subform!' };
    }
  
    registerOnValidatorChange(fn: () =&gt; void): void {
      this.addressForm.statusChanges.subscribe(fn);
    }
  }
  
  @NgModule({
    imports: [
  
      CommonModule,
      FormsModule,
      ReactiveFormsModule
  
    ],
    exports: [AddressFormComponent],
    declarations: [
      AddressFormComponent
    ],
    entryComponents: [AddressFormComponent],
    providers: [
  
    ]
  })
  
  export class AddressFormModule { }
  </code></pre>
  
  <p>View:</p>
  
  <pre><code>&lt;form [formGroup]="addressForm"&gt;
  
    &lt;div class="row"&gt;
        &lt;div class="form-group col-md-10"&gt;
            &lt;label for="txtVia"&gt;Via&lt;/label&gt;
            &lt;input type="text" pInputText class="form-control" id="txtVia"
                formControlName="via"&gt;
                &lt;div *ngIf="!addressForm.controls['via'].valid &amp;&amp; (addressForm.controls['via'].dirty || addressForm.controls['via'].touched)"
                class="alert alert-danger"&gt;
                Campo obbligatorio
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="form-group col-md-2"&gt;
            &lt;label for="txtCivico"&gt;Civico&lt;/label&gt;
            &lt;input type="text" pInputText class="form-control" id="txtCivico"
                formControlName="civico"&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="row"&gt;
        &lt;div class="form-group col-md-3"&gt;
            &lt;label for="txtCap"&gt;Cap&lt;/label&gt;
            &lt;input type="text" pInputText class="form-control" id="txtCap"
                formControlName="cap"&gt;
        &lt;/div&gt;
        &lt;div class="form-group col-md-6"&gt;
            &lt;label for="txtComune"&gt;Comune&lt;/label&gt;
            &lt;input type="text" pInputText class="form-control" id="txtComune"
                formControlName="comune"&gt;
        &lt;/div&gt;
        &lt;div class="form-group col-md-3"&gt;
            &lt;label for="txtProvincia"&gt;Provincia&lt;/label&gt;
            &lt;input type="text" pInputText class="form-control" id="txtProvincia"
                formControlName="provincia"&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="form-group"&gt;
        &lt;label for="txtFrazione"&gt;Frazione&lt;/label&gt;
        &lt;input type="text" pInputText class="form-control" id="txtFrazione"
            formControlName="frazione"&gt;
    &lt;/div&gt;
    &lt;div class="row"&gt;
        &lt;div class="form-group col-md-6"&gt;
            &lt;label for="txtRegione"&gt;Regione&lt;/label&gt;
            &lt;input type="text" pInputText class="form-control" id="txtRegione"
                formControlName="regione"&gt;
        &lt;/div&gt;
        &lt;div class="form-group col-md-6"&gt;
            &lt;label for="txtStato"&gt;Stato&lt;/label&gt;
            &lt;input type="text" pInputText class="form-control" id="txtStato"
                formControlName="stato"&gt;
        &lt;/div&gt;
    &lt;/div&gt;
  
  &lt;/form&gt;
  </code></pre>
  
  <p>I bind it to a parent form this way:</p>
  
  <p>view:</p>
  
  <pre><code>&lt;form (submit)="onConfirm($event)" *ngIf="aziendaform" [formGroup]="aziendaform"&gt;
      &lt;app-address-form formControlName="indirizzoSpedizione"&gt;&lt;/app-address-form&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>code:</p>
  
  <pre><code>import { Component, Input, Output, EventEmitter, OnInit, SimpleChanges, OnChanges, ChangeDetectorRef } from '@angular/core';
  import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
  
  @Component({
      selector: 'app-azienda-form',
      templateUrl: 'aziende-form.component.html'
  })
  export class AziendeFormComponent implements OnInit, OnChanges {
  
      aziendaform: FormGroup;
  
  
      constructor(
          private fb: FormBuilder,
          private cdr: ChangeDetectorRef
      ) {
      }
  
      ngOnChanges(changes: SimpleChanges) {
  
      }
  
      ngOnInit(): void {
  
          this.aziendaform = this.fb.group({          
              'indirizzoSpedizione': new FormControl(null)         
          });
  
          this.cdr.detectChanges();
      }
  
      validateAllFormFields(formGroup: FormGroup) {
          Object.keys(formGroup.controls).forEach(field =&gt; {
              const control = formGroup.get(field);
              if (control instanceof FormControl) {
                  control.markAsTouched({ onlySelf: true });
              } else if (control instanceof FormGroup) {
                  this.validateAllFormFields(control);
              }
          });
      }
  
      onConfirm(event) {
          event.preventDefault();
  
          if (this.aziendaform.valid) {
              /*
                  do somithing
              */
          } else {
              this.validateAllFormFields(this.aziendaform);
          }
      }
  
  }
  </code></pre>
  
  <p>When I press confirm button the form is invalid but in the child component there are no error messages.
  It seems that <code>markAsTouched</code> does not propagate to child form.</p>
  
  <p>Can someone help me?</p>
  
  <p><strong><em>update</em></strong></p>
  
  <p>I prepared a StackBlitz here:
  <a href="https://stackblitz.com/edit/angular-4qcsox" rel="nofollow noreferrer">https://stackblitz.com/edit/angular-4qcsox</a></p>
  
  <p>As you can see confirm and reset button does not affect child component.</p>