CodyBugstein
CodyBugstein

Reputation: 23312

My nested Angular reactive form is not getting the FormGroup from the parent component

I came across Kara Erickson's demo of Angular forms at AngularConnect 2017, on YouTube. The part I'm specifically interested is where she describes nested reactive forms

I've done everything as Kara describes, but I end up getting a null parentForm no matter what I try.

I've reproduced a simplified version of my code below. The problem is that in the child-form component I am getting null.

// PARENT COMPONENT

@Component({
  selector: 'parent-form',
  styleUrls: ['./parent-form.component.css'],
  template: `
    <form [formGroup]="createAlbumProfileForm" (ngSubmit)="onFormSubmitted($event)">
        <input type="text" placeholder="Something unique to parent form"/>
        <child-form></child-form>
    </form>
  `
})
export class ParentFormComponent implements OnInit {

  parentForm: FormGroup;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.parentForm = this.formBuilder.group({
      yoloField: this.formBuilder.control('')
    });
  }

// CHILD COMPONENT

@Component({
    selector: 'child-form',
    styleUrls: [ './child-form.component.scss' ],
    viewProviders:[ { provide: ControlContainer, useExisting: FormGroupDirective } ],
    template: `
      <div formGroupName="songName" class="form-group"></div
    `
})
export class ChildFormComponent implements OnInit {
    childForm: FormGroup;

    constructor(private parentForm: FormGroupDirective) {
        this.childForm = parentForm.form; // null
    }
}

Upvotes: 5

Views: 3122

Answers (2)

yannick1976
yannick1976

Reputation: 11565

I ran into the same problem and actually it didn't work to have both forms initializations in constructors. It did to either do have both in ngOnInit, or the parent init in the constructor and the child init in the ngOnInit.

It's probably better to put everything in ngOnInit then, otherwise it won't work if there is one more level of nesting.

So:

PARENT COMPONENT:

@Component({
  //...
})
export class ParentFormComponent implements OnInit {

  // ...

  ngOnInit() {
    this.parentForm = this.formBuilder.group({});
  }

CHILD COMPONENT:

@Component({
    // ...
})
export class ChildFormComponent implements OnInit {
    childForm: FormGroup;

    constructor(private parent: FormGroupDirective) {
    }

    ngOnInit() {
        this.childForm = new FormGroup(/*....*/);
        this.parentForm.form.addControl('childData', this.childForm);
    }
}

Upvotes: 2

Yevgeniy.Chernobrivets
Yevgeniy.Chernobrivets

Reputation: 3194

It seems like it is problem with life cycle of the components: in video FormGroup is initialized in constructor of parent component but in your example you initialize it OnInit. The problem is that child's constructor is called before parent's OnInit that is why you are getting null.

Upvotes: 6

Related Questions