Reputation: 321
So I have a slightly unusual use case. To simplify, I'm getting a list of something we shall call "templates" from the backend. Each of these templates has a different number of template variables that go along with it (eg. one template might have 3 variables, another might have 2). A template along with user provided values for each template variable makes up a story.
So what I want to do is have a form that lets users create a story. Basically the form component will load a list of templates received from the backend. Now when they select a template from a dropdown list, I want to dynamically generate inputs for each of the variables. So far I have an input where the user enters a template name. I then generate a nested FormGroup on the fly that has a FormControl for each of the variables.
This is what I have so far: https://stackblitz.com/edit/angular-kt7rib
I am very close. For example, if you enter template1
into the input, it will generate two additional inputs for the variables for that template. However I get the following error message in the console: Error: Cannot find control with path: 'templateVariables -> variable1'
. This is preventing me from getting the values from the top level FormGroup and sharing the validation logic from the child FormGroup.
I have an inkling that it's due to the fact that I'm dynamically generating the FormGroup, and so it doesn't get bound properly to the top level FormGroup.
How should I fix this? Thanks.
Upvotes: 0
Views: 101
Reputation: 57929
it's only one deep?
In that case, for me, at first you defined your form like
this.form = this.fb.group({
templateName: this.templateName,
});
When change use addControl
this.templateName.valueChanges.subscribe(val => {
if (val && this.templateNameMap.hasOwnProperty(val)) {
const variables = {};
for (const key of Object.keys(this.templateNameMap[val])) {
variables[key] = new FormControl("", [Validators.required]);
}
this.form.addControl("templateVariables",this.fb.group(variables))
}
//I use this.templateVariables to "point" to the formGroup created
this.templateVariables=(this.form.get('templateVariables') as FormGroup);
});
Finally, for iterating, if you use Angular 8 -why do you use Angular 6?- you can use |keyvalue
<form formGroupName="templateVariables">
<input *ngFor="let varName of templateVariables.controls| keyvalue"
[formControlName]="varName.key">
<br>
</form>
NOTE: Always we work with dinamic reactiveForms it's good add to the .html some like {{form?.value|json}} to see if we are creating the form as we want
Upvotes: 1