Pass Angular Reactive FormControls to Children Components

24,708

It's not too tough, once you know what to look for. If you have never done it before, it can be a challenge. The error messages you get don't always help.

First, you want to add some things to your DetailsFields component. The new Inputs will allow you to pass in the instance of the form group you constructed in your parent component. The car and carIndex inputs will be used to pass in the values the child component will need in order to work like you have them now.

import { Component, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';

@Component({
    selector: 'app-child',
    templateUrl: './details-fields.component.html',
    styleUrls: ['./details-fields.component.css']
})

export class DetailsFields implements OnInit {
    @Input() form: FormGroup;
    @Input() car: any;
    @Input() carIndex: number;

    ngOnInit() { }
}

Second, you want to move some of the template HTML you have in you parent component to the child component. The child component template (details-fields.component.html) will look like this in the end. The [formGroup]="form" in the first div is the real key here. That is what tells the child template what form group to use. You pass this from the parent in the code after this.

<div [formGroup]="form">
    <div class="car-wrap" formArrayName="cars">
        <div [ngClass]="car.make + '-car'" [formGroupName]="carIndex">
            <p class="title">This car is a {{car.make}}</p>
            <div formGroupName="details">
              <input type="text" formControlName="make">
              <input type="text" *ngIf="car.make != 'ford'" formControlName="model">
              <input type="number" formControlName="year">
            </div>
            <div formGroupName="appearance">
              <input type="text" formControlName="color">
            </div>
        </div>
    </div>
</div>

The parent component template will be only left with this. This is where you pass the carsForm form group to the child component, along with the car and the carIndex.

<div id="cars" [formGroup]="carsForm">
    <div *ngFor="let car of cars; let i = index;">
        <app-child [form]="carsForm" [car]="car" [carIndex]="i"></app-child>
    </div>
</div>

The last thing I did was move the styles you had in the parent component out to the styles.css file, so all components could use them.

That's it! Really just moving some code around and adding some inputs so you can pass the child what it needs.

Share:
24,708

Related videos on Youtube

JordanBarber
Author by

JordanBarber

I am a UI Developer and Designer focused on modern javascript frameworks. Most recently, I have been using Angular (2+) for the past two and a half years, but I also have experience with React, Vue and Aurelia. I strive in a team environment in which I can work with others to turn ideas and designs into highly usable experiences. I have expert experience with Javascript, Angular, Aurelia, Git, HTML, CSS/SASS, Wordpress, Drupal, Webpack, NPM, Adobe Illustrator and Sketch. Always striving to learn more.

Updated on June 16, 2020

Comments

  • JordanBarber
    JordanBarber almost 4 years

    I have a parent component where I want to create and store my Reactive Form. There will be multiple Form Group instances in a Form Array. I want to pass the Form Controls from each Form Group to a Child Component but am having trouble figuring out how to do this.

    Here's a Stackblitz demonstrating what I would like to do. Also, some fields will only apply to certain 'makes' of cars which is why i have the following line in my html:

    <input type="text" *ngIf="car.make != 'ford'" formControlName="model">
    

    I would like to move the 'Details' Form Group fields into the 'details-fields' child component but when I try to do that, it tells me that I don't have a Form Group instance so I know the parent Form Group is not registering in the child component. Any help is much appreciated.

    • Surendranath Sonawane
      Surendranath Sonawane almost 4 years
      Refer this link it might help you.
  • J E Carter II
    J E Carter II over 5 years
    Thanks @R., the specific part of your example that helped me was that the parent passes a singular pointer to an element to the child, no the entire array of values. eg car, not cars.
  • Vasim
    Vasim about 5 years
    I have similar scenario except I am displaying search result in child component based on form submitted from parent component, any idea how to do that?
  • baHI
    baHI over 4 years
    @R. Richards although this solution is valid, but what if I do want to keep the formGroup in the parent? It should work, as it is permitted with template driven forms and of course it should be always the parent that should decide if it wants to reuse something in a new group or in existing one.
  • Colin Rickels
    Colin Rickels over 3 years
    now for the real question @R. Richards can this be done recursively for as many fields that are dynamically generated. So if im taking a json structure froma. server and generating a group as deeply nested as the json dictates, can i recursively keep passing that parent form group into each child.
  • Elham abbasi
    Elham abbasi almost 3 years
    Is there a stackblitz for this solution? I tried the same approach, but it didn't work for me