title: How to avoid duplicates of form fields and validations of forms accross angular application?
body: <p>I am new to angular.</p>
  
  <p>I am building a application which have contact and subscribe form, which is common in websites. Both of these forms have first name, last name and email fields. I was duplicating html markup and validation for these two forms. </p>
  
  <p>So I decided to extract common fields to a separate component and inorder to  avoid duplication but I am struggling to pass values from child component to parent and keeping submit button disabled incase of invalid input in child component.</p>
  
  <p>My current code is given below. </p>
  
  <p><strong>personalinfo.component.html</strong></p>
  
  <pre><code>&lt;div [formGroup]="personalInfoForm" novalidate&gt;
    &lt;div class="firstName"&gt;
      &lt;mat-form-field&gt;
        &lt;input matInput placeholder="First Name" 
               formControlName="firstName"&gt;
  
        &lt;mat-error [hidden]="personalInfoForm.hasError('required', 'firstName')"&gt;
          Please provide first name
        &lt;/mat-error&gt;
  
      &lt;/mat-form-field&gt;
    &lt;/div&gt;
  
    &lt;div class="lastName"&gt;
      &lt;mat-form-field&gt;
        &lt;input matInput placeholder="Last Name" formControlName="lastName"&gt;
        &lt;mat-error [hidden]="personalInfoForm.hasError('required', 'lastName')"&gt;
          Please provide last name
        &lt;/mat-error&gt;
      &lt;/mat-form-field&gt;
    &lt;/div&gt;
  
    &lt;div class="email"&gt;
      &lt;mat-form-field&gt;
        &lt;input matInput placeholder="Email" formControlName="email"&gt;
  
        &lt;mat-error *ngIf="personalInfoForm.hasError('required', 'email')"&gt;
          Please provide an email
        &lt;/mat-error&gt;
        &lt;mat-error *ngIf="personalInfoForm.hasError('pattern', 'email') &amp;&amp; 
                         !personalInfoForm.hasError('required', 'email')"&gt;
          Invalid email
        &lt;/mat-error&gt;
      &lt;/mat-form-field&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>personalinfo.component.ts</strong></p>
  
  <pre><code>import { Component, OnInit, Input } from '@angular/core';
  import { Validators, FormBuilder, FormGroup } from '@angular/forms';
  
  @Component({
    selector: 'app-personalinfo',
    templateUrl: './personalinfo.component.html',
    styleUrls: ['./personalinfo.component.scss']
  })
  export class PersonalinfoComponent implements OnInit {
  
    readonly EMAIL_REGEX = "[a-zA-Z0-9.-_]{1,}@[a-zA-Z0-9.-_]{1,}.[a-zA-Z]{2,}";
  
  
    personalInfoForm: FormGroup;
  
    constructor(private fb: FormBuilder) {
  
      this.createPersonalInfoForm();
     }
  
  
     createPersonalInfoForm() {
  
      this.personalInfoForm = this.fb.group({
        firstName: ['', Validators.required],
        lastName: ['', Validators.required],
        email: ['', [Validators.required, Validators.pattern(this.EMAIL_REGEX)]],
  
      });
    }
    ngOnInit() {
    }
  
  }
  </code></pre>
  
  <p><strong>contact.component.html</strong></p>
  
  <pre><code>&lt;div class="form-contact" flexLayout="row" fxLayoutAlign="center"&gt;
  
  
    &lt;form [formGroup]="contactForm" 
          novalidate 
          (ngSubmit)="sendMessage(contactForm.value, contactForm.invalid)"&gt;
  
  
      &lt;app-personalinfo&gt;&lt;/app-personalinfo&gt; 
  
  
  
      &lt;div class="subject"&gt;
        &lt;mat-form-field&gt;
          &lt;input matInput
                 placeholder="Subject"
                 formControlName="subject" &gt;
          &lt;mat-error   *ngIf="contactForm.hasError('required', 'subject')"&gt;
            Please provide a subject
          &lt;/mat-error&gt;
          &lt;mat-error   *ngIf ="contactForm.hasError('minlength', 'subject') &amp;&amp;
                              !contactForm.hasError('required', 'subject')"&gt;
            Minimum 5 characters
          &lt;/mat-error&gt;
  
        &lt;/mat-form-field&gt;
      &lt;/div&gt;
  
      &lt;div class="message"&gt;
        &lt;mat-form-field&gt;
          &lt;textarea matInput 
                    placeholder="Message" 
                    matTextareaAutosize 
                    matAutosizeMinRows="5" 
                    matAutosizeMaxRows="10"
                    formControlName="message"&gt;
          &lt;/textarea&gt;
          &lt;mat-error  *ngIf ="contactForm.hasError('required', 'message')"&gt;
            Please provide a message
          &lt;/mat-error&gt;
          &lt;mat-error   *ngIf ="contactForm.hasError('minlength', 'message') &amp;&amp;
                              !contactForm.hasError('required', 'message')"&gt;
            Minimum 10 characters
          &lt;/mat-error&gt;
        &lt;/mat-form-field&gt;
      &lt;/div&gt;
  
      &lt;button mat-button 
              color="primary" 
              type="submit" 
              [disabled]="contactForm.invalid"&gt;
              Submit
      &lt;/button&gt;
  
    &lt;/form&gt;
  
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>contact.component.ts</strong></p>
  
  <pre><code>import { Component, OnInit } from '@angular/core';
  import { FormControl, Validators, FormBuilder, FormGroup } from '@angular/forms';
  // interface with fields (firstName, lastName and etc)
  import { User } from '../user';
  
  @Component({
    selector: 'app-contact',
    templateUrl: './contact.component.html',
    styleUrls: ['./contact.component.scss']
  })
  export class ContactComponent implements OnInit {
  
  
    contactForm: FormGroup;
  
    constructor(private fb: FormBuilder) {
  
      this.createContactForm();
     }
  
  
     createContactForm() {
      this.contactForm = this.fb.group({
        subject: ['', [Validators.required, Validators.minLength(5)]],
        message: ['', [Validators.required, Validators.minLength(10)]]
      });
    }
  
  
    ngOnInit() {
    }
  
    sendMessage(user, isInvalid: boolean)
    {
        if(!isInvalid){
  
          console.log(user);
  
           console.log(user.firstName);
           console.log(user.lastName);
           console.log(user.email);
           console.log(user.subject)
           console.log(user.message);
  
        }
    }
  
  }
  </code></pre>
  
  <p>I found several questions, but things are not clear. Any help would be highly appreciated.</p>