5

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
    }
}
4
  • 1
    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. Commented Feb 26, 2018 at 18:27
  • your child component should implement ControlValueAccessor interface from "@angular/forms" in that way from your parent component will be able to assign a formcontrolname to his child component Commented Feb 26, 2018 at 18:35
  • @Yevgeniy.Chernobrivets bingo! That was causing the problem, thank you! Commented Feb 26, 2018 at 18:44
  • @Ricardo do you have an example describing more about what you mean? I don't understand Commented Feb 26, 2018 at 18:45

2 Answers 2

6

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.

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

1 Comment

You have given the cause - could you also describe a solution? Thanks!
2

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);
    }
}

1 Comment

what I'm calling the "two inits" are the code 1) in the ngOnInit in the parent component in the OP's question and 2) in the constructor of the child in the OP's question. Hope this is clearer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.