Issue
I am trying to make a reactive form with dynamic input
so I created the reactive form component like this
main_component.ts
constructor(private formBuilder: FormBuilder) {
this.operationGroupForm = this.formBuilder.group({
'operation': '',
'searchTerm': ''
});
}
main_component.html
<form [formGroup]="operationGroupForm">
<input type="text" formControlName="operation">
<div operationClass [type]="'mycustomtype'"
[_formControlName]="'searchTerm'"></div>
</div>
</form>
and created the directive operationClass that appended to the div and inject the component into the div
operationClass.directive.ts
constructor(private el: ElementRef, private render: Renderer2, private viewContainerRef: ViewContainerRef,
private componentFactory: ComponentFactoryResolver) {}
ngOnInit(): void {
var comRef = this.componentFactory.resolveComponentFactory(input_component);
var _comRef = this.viewContainerRef.createComponent(comRef);
_comRef.instance.formControlName = this._formControlName;
_comRef.instance.type = this.type;
}
and that component renders the right input by taking the formControlName and type and rendering the input on the custom condition
and that component for rendering input is : input_component.ts
@Input() formControlName: string;
@Input() type: string;
constructor() {
}
ngOnInit(): void {
}
input_component.html
<ng-container *ngIf="type">
<ng-container [ngSwitch]="type">
<ng-container *ngSwitchCase="'mycustomtype'">
<input type="text" [formControlName]="formControlName" class="form-control" />
</ng-container>
<ng-container *ngSwitchDefault>
<input type="number" [formControlName]="formControlName" class="form-control" />
</ng-container>
</ng-container>
</ng-container>
the problem is that as I think the inner input formControlName can't see the outer formGroup because it generates that error
ERROR Error: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup
directive and pass it to an existing FormGroup instance (you can create one in your class).
Example:
<div [formGroup]="myGroup">
<input formControlName="firstName">
</div>
In your class:
this.myGroup = new FormGroup({
firstName: new FormControl()
});
at Function.controlParentException (forms.js:1692)
at FormControlName._checkParentType (forms.js:6059)
at FormControlName._setUpControl (forms.js:6063)
at FormControlName.ngOnChanges (forms.js:5995)
at FormControlName.rememberChangeHistoryAndInvokeOnChangesHook (core.js:2131)
at callHook (core.js:3042)
at callHooks (core.js:3008)
at executeInitAndCheckHooks (core.js:2960)
at refreshView (core.js:7331)
at refreshEmbeddedViews (core.js:8408)
Solution
Consider applying to your code the following changes:
main_component.ts
The value for each control name is an array containing the initial value as the first item in the array. (Angular Docs)
constructor(private formBuilder: FormBuilder) {
this.operationGroupForm = this.formBuilder.group({
'operation': [''], // <== provide an array
'searchTerm': [''] // <== provide an array
});
}
input_component.ts
Since formControlName must be used with a parent formGroup directive you'll want to add a formGroup directive and pass it your formGroup instance, rather than passing your formGroup instance along you can inject it in your child component using ControlContainer as demonstrated below:
import { FormGroup, ControlContainer } from '@angular/forms';
...
@Input() formControlName: string;
@Input() type: string;
public formGroup: FormGroup;
constructor(public controlContainer: ControlContainer) { // <== inject reference to formGroup via ElementInjector
this.formGroup = controlContainer.control as FormGroup
}
input_component.html
<ng-container *ngIf="type">
<ng-container [ngSwitch]="type" [formGroup]="formGroup"> <!-- <== pass injected form -->
<ng-container *ngSwitchCase="'mycustomtype'">
<input type="text" [formControlName]="formControlName" class="form-control" />
</ng-container>
<ng-container *ngSwitchDefault>
<input type="number" [formControlName]="formControlName" class="form-control" />
</ng-container>
</ng-container>
</ng-container>
For further information about FormContainer
Answered By - Rafi Henig
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.