Passing FormGroup across multiple components

adeelmahmood picture adeelmahmood · May 1, 2017 · Viewed 9.1k times · Source

I am using reactive forms in an angular 2+ application and there is a need to pass the main FormGroup to multiple components so that different parts of the form e.g. header, footer etc can be managed in separate components and populated by those different components. This is how I am doing it, at the moment:

<div class="container-fluid">
  <form [formGroup]="orderForm">
    <order-header [orderForm]="orderForm"></order-header>
    <order-items [orderForm]="orderForm"></order-items>
    <order-footer [orderForm]="orderForm"></order-footer>
  </form>
</div>

I am wondering, if this is a correct approach coz I do see a warning/error with this code:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.

On this line:

<form [formGroup]="orderForm">

Any suggestions? Thanks.

Answer

AJT82 picture AJT82 · May 2, 2017

As mentioned by Julia, this is normal behavior.

It's actually the @Input in your components that are causing this, not the line <form [formGroup]="orderForm">

This happens during dev mode. How you can get around this problem, is to manually trigger change detection in the components that receive the orderForm. Since you are using @Input, you can use the ngOnChanges life cycle hook in your other components:

import { ChangeDetectorRef } from '@angular/core';

@Input() orderForm: FormGroup

constructor(private ref: ChangeDetectorRef) { }

ngOnChanges() {
  this.ref.detectChanges()
}

Check more here about your error: Expression ___ has changed after it was checked

Also, as a sidenote, do you really need to pass the complete form to your other components. Usually we pass just the nested group that the component will handle, so something like this:

<form [formGroup]="orderForm">
  <order-header [orderForm]="orderForm.controls.myNestedGroupName"></order-header>
</form>

Just as a sidenote! :)