Angular 4 - Error: formControlName must be used with a parent formGroup directive

You need to pass formGroup (in your case contact_form) to child component which is ang-form

engine-add-contact-form.html(modified)

<form (ngSubmit)="onSubmit()" [formGroup]="contact_form">
<md-tab-group>
    <md-tab label="Form">
        <ang-form [group]="contact_form"></ang-form>
    </md-tab>
    <md-tab label="Email">
        <ang-email></ang-email>``
    </md-tab>
    <md-tab label="Message">
        <ang-message></ang-message>
    </md-tab>
</md-tab-group>
<button md-raised-button type="submit">Publish</button>

ang-form.html(modified)

<div class="form-grid form-title" [formGroup]="group">
     <md-input-container>
         <input formControlName="contact_form_title" 
        class="form-title-field" mdInput placeholder="Title" value="">
     </md-input-container>
</div>

Add @Input() group: FormGroup; in your ang-form.component.ts


There are a lot of options of doing this.

1) Here is an example that uses formControl directive and angular DI system:

@Component({
  selector: 'ang-form',
  template: `
    <input [formControl]="control">
  `
})
export class AngForm {
  control: FormControl;

  constructor(private formGroupDir: FormGroupDirective) {}

  ngOnInit() {
    this.control = this.formGroupDir.control.get('contact_form_title') as FormControl;
  }
}

Stackblitz Example

2) Another way it to define ControlContainer view provider on child component:

@Component({
  selector: 'ang-form',
  template: `
     <input formControlName="contact_form_title">
    `,
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class AngForm { }

Stackblitz Example

For more examples see:

  • Nested arrays in Angular 2 reactive forms?

  • Angular2 nested template driven form

Tags:

Angular