I am trying to create a forms component where the component provides the <form>
and its descendants the form content, i.e. control. I am using RC4 with reactive forms. The component should be used like this:
<my-formwizard [form]="form">
<input formControlName="name" type="text" />
</my-formwizard>
Here's a plunk showing the implementation: http://plnkr.co/edit/OSzjDQD63lwoEsyqdLvw?p=preview
I run into an exception: TypeError: Cannot read property 'setParent' of null
Is there a way to accomplish a reactive form spread across multiple components?
UPDATE: RC5 has a clearer error message and thanks to peeskillet's input, formControlName
can be used if the custom directive gets the FormGroup
attached through the formGroup
property. The updated plunk shows the form spread across two components working:
http://plnkr.co/edit/1VfIH5AYjoe7dmizw6ss?p=preview
In you Plunker, I'm not sure why you have the ngForm
<my-formwizard [form]="form" ngForm="form">
but that shouldn't be there. I think it may even be creating a whole new form. That should be removed. Once you remove that, then you will run into another problem, saying that there is no ControlContainer
. The ControlContainer
is the FormGroupDirective
([formGroup]
).
The problem is caused by the formControlName
. If you look at the source for the FormControlName
directive, and you look at the constructor, you will see that it requires a ControlContainer
dependency. But not just that, it also has a @Host
1 decorator, which means it will only look for the ControlContainer
in the host injector.
Honestly I'm not quite sure in this case which injector is used as the host injector in this case, but it appears it is not the one with the form group directive. Maybe because how you have the components set up.
A solution I found it to instead of using formControlName
, use [formControl]
instead, and just pass a FormControl
instance. The FormControlDirective
does not have this problem (where it needs a ControlContainer
), as it is possible to be used in standalone.
So you could do this instead
<input [formControl]="nameCtrl" type="text" />
export class App {
form: FormGroup;
nameCtrl: FormControl;
constructor(fb: FormBuilder) {
this.nameCtrl = new FormControl('');
this.form = fb.group({
name: this.nameCtrl
});
}
}
This solves your problem. Here's the updated Plunker,
See Also:
1 - See Host and Visibility... for a good read on this topic
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With