14

I am trying to create an Angular 5 nested reactive form.

I started by creating a flat form, which worked as expected, but as soon as I extract part of my form and place it in as a child component I get an error

ERROR TypeError: Cannot create property 'validator' on string 'addressFormGroup'

If I just start typing another error is then displayed in the console

ERROR TypeError: this.form.get is not a function

What am I doing wrong? I've read several threads and tutorials to try and solve this, but I think i'm missing something obvious.

import { Component, OnInit } from '@angular/core'
import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Address } from '../Property';

@Component({
moduleId: module.id,
selector: 'app-property-form',
templateUrl: './property-form.component.html',
styleUrls: ['./property-form.component.css']
})
export class PropertyFormComponent implements OnInit {

propertyForm: FormGroup;

constructor(private _formBuilder: FormBuilder) {}

ngOnInit() {
    this.createForm();
}

createForm() {
    this.propertyForm = this._formBuilder.group({
        saleOrLet: ['Sales', Validators.required],
        addressFormGroup: this.initAddress()
    })
}

initAddress() {
    return this._formBuilder.group({
        houseNameNumber: '',
        address2: '',
        postCode1: '',
        postCode2: ''
    })
}
}

Working form

<form [formGroup]="propertyForm" novalidate>
<fieldset>
<legend>Address</legend>
<div formGroupName="addressFormGroup">
  <div class="form-group">
    <label>
      House Name Or Number:
      <input placeholder="15 Nursery ave" formControlName="houseNameNumber">
    </label>
  </div>
  ...other inputs follow the same pattern...
</div>
</fieldset>
</form>

Broken form (when split in to parent child format)

Parent

<form [formGroup]="propertyForm" novalidate>
  <fieldset>
    <legend>Address 2</legend>
    <app-property-form-address group="addressFormGroup"></app-property-form-address>
  </fieldset>
</form>

Child

<div [formGroup]="group">
 <div class="form-group">
    <label>
      House Name Or Number:
      <input placeholder="15 Nursery ave" formControlName="houseNameNumber">
    </label>
  </div>
  ...other inputs follow the same pattern...
</div>

Child component

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

@Component({
   selector: 'app-property-form-address',
   templateUrl: './property-form-address.component.html',
})
export class PropertyFormAddressComponent {
    @Input() group: FormGroup;
}
3
  • Inside initAddress use array. Something like address2:[‘’] Commented Jan 26, 2018 at 0:18
  • 2
    Your @grup is a string, not a FormControl or FormGroup. Try <pp-property-form-address group="propertyForm.get('addressFormGroup')"..>. Anyway, you can try make a "custom Form Control", not, simple component Commented Jan 26, 2018 at 7:36
  • 1
    @tony09uk i have same issue Commented Feb 5, 2018 at 6:54

5 Answers 5

18

You're passing the form group name as a string rather than a reference to the formGroup and trying to typecast it as a FormGroup (group="addressFormGroup"). group="addressFormGroup" doesn't pass the formGroup object, it passes a string with the value of addressFormGroup.

Sign up to request clarification or add additional context in comments.

2 Comments

What was the solution? Typecasting to FormGroup like this didn't work for me: <app-property-form-address group="<FormGroup>propertyForm.get('addressFormGroup')"></app-property-form-address>
@annepic try [group]="addressFormGroup" - by calling group="" you're still passing a string. You need to use property binding with angular, I suggest you read up on template syntax and binding in general (angular.io/guide/template-syntax)
8

I had a same issue and I was passing form object as a value like formGroup="form" but you need to bind the form object using [] aroung as [formGroup]="form".

See the example below:

<form [formGroup]="form">
    // form-controls
</form>

Comments

8

You can get a similar error message if you have:

<input formControl="startDate">

From the docs it should be:

<input formControlName="startDate">

And everything should be fine.

Comments

2

Same problem occured because of the wrong implementation of formgroup and formControl. Fixed this by the following implementation.

formGroup='' renamed to formGroupName=''.

formControl='' renamed to formControlName=''.

Comments

1

For me the problem was on the control side, I had to change from

<input formControl="startDate">

to this

<input [formControl]="startDate">

So this structure should work

<form [formGroup]="form">
    // form-controls
    <input [formControl]="startDate">
</form>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.