37

I have component which has a form and some child components within the form. The child components are created using *ngFor and each child contains input elements. Angular2 compiler is giving errors like [formGroup] is not defined.

Is this implementation a correct?

Parent Component:

<section class="data-body">
        <form [formGroup]="checkoutForm" novalidate>
            <app-checkout-product-view *ngFor="let item of checkoutData.products" [_product]="item" formGroupName="products"></app-checkout-product-view>
                <div class="col-md-4">
                    <label>Nominee:</label>
                    <select required [(ngModel)]="checkoutData.selectedNominee" [ngModelOptions]="{standalone: true}">
                        <option *ngFor="let nominee of checkoutData.nomineeList" [value]="nominee">{{nominee}}</option>
                    </select>
                </div>
                <div class="col-md-4">
                    <label>Bank Account:</label>
                    <select [(ngModel)]="checkoutData.selectedBank" required [ngModelOptions]="{standalone: true}">
                        <option *ngFor="let bank of checkoutData.bankList" [value]="bank">{{bank}}</option>
                    </select>
                </div>
            </div>
        </form>
    </section>

Child Component: app-checkout-product-view

<div class="row">
    <div class="col-md-4">
        <md-input required [(ngModel)]="product.investmentAmount 
                  formControlName="investmentAmount">
            <span md-prefix>&#x20B9;</span><!--Rupee icon-->
        </md-input>
    </div>
</div>

P.S. : All the imports are fine so I am pretty sure that no import errors here

Jacob Stamm
  • 1,660
  • 1
  • 29
  • 53
Sumit Agarwal
  • 4,091
  • 8
  • 33
  • 49

2 Answers2

67

This behavior is expected. Angular forms are not automatically registered when inside nested component. However you can workaround this by providing the outer FormGroup to the child component. And inside the child component wrap the template inside that same group. Here is how this might look:

/outer component code - it contains the form/

@Component({
  selector: 'my-app',
  template: `
    <form [formGroup]="reactiveFormGroup">
      <input formControlName="foo" />
      <my-comp **[group]="reactiveFormGroup"**></my-comp>
    </form>

    form value: {{ reactiveFormGroup.value | json }}
  `
})
export class AppComponent { 
  reactiveFormGroup = new FormGroup({
    foo: new FormControl('default foo'),
    bar: new FormControl('default bar')
  });
}

/child component code, i.e my-comp/

@Component({
  selector: 'my-comp',
  template: `
    <div [formGroup]="group">
      <input   [formControlName]="'bar'" />
    </div>
  `
})
export class MyComponent { 
  @Input() group: FormGroup;
}
Jacob Stamm
  • 1,660
  • 1
  • 29
  • 53
rusev
  • 1,880
  • 2
  • 17
  • 14
  • 5
    There is a recent blog post that goes though an example of this as well. You can find it here: https://toddmotto.com/component-architecture-reactive-forms-angular – DeborahK May 11 '17 at 16:00
  • 1
    hi @DeborahK is the answer by rusev above still the best answer for Angular 8 in year 2019? Thanks –  Dec 12 '19 at 07:01
  • Hey @TomBook I suspect that it is still the case and thank you. At the time of writing this post I was already a several months into development of UI library based on Angular and I have to say that I hit a ton of "corner" cases. At that time there wasn't many posts on the subject, so when I had time I decided to give back to the community. These days I don't use Angular anymore. – rusev Dec 12 '19 at 13:52
  • hi @rusev what do you use these days for new framework? I keep hearing "I don't use Angular anymore" Do you utilize React or Vue? –  Dec 12 '19 at 17:44
  • Mostly React, but I also experiment with Elm and Svelte. – rusev Dec 13 '19 at 07:38
  • For others who get here, this won't work for template driven forms but this will: https://stackoverflow.com/a/46748943/1316683 – MDave Feb 08 '20 at 00:31
  • Updated link to the blog post mentioned in comments here: https://ultimatecourses.com/blog/component-architecture-reactive-forms-angular – Slartibartfast Jun 29 '23 at 10:15
3

You're saying the imports are fine but the errors you're getting suggest that they probably are not.

[formGroup] is not defined errors are usually caused by a missing
import { ReactiveFormsModule } from '@angular/forms' inside the module where your component is declared.

Besides that, you should not use [(ngModel)] inside model-driven forms but instead rely on [formGroup] and formControlName.

Siri0S
  • 678
  • 1
  • 6
  • 10
  • these are my imports `import {FormGroup, FormBuilder, Validators} from "@angular/forms";` – Sumit Agarwal Oct 21 '16 at 09:01
  • Secondly is it okay to have child components within the form? – Sumit Agarwal Oct 21 '16 at 09:04
  • These are the imports you need inside your component class. But that component must be declared inside a module. Inside that module you need to register _**ReactiveFormsModule**_ as an import inside the `imports: []` array. – Siri0S Oct 21 '16 at 09:05
  • Module level imports are also fine, the whole thing is working in other component which has no child components in the form – Sumit Agarwal Oct 21 '16 at 09:07
  • Perhaps I could be of more help if you posted your _component.ts_ and _module.ts_ files. – Siri0S Oct 21 '16 at 09:12