Reputation: 3072
I have the following JSON which I wish to map out to a form:
{
"lineItemId": 0,
"count": 0,
"fixtures": [
{
"fixtureId": 0,
"fixtureName": "string",
"total": 0,
"completed": 0,
"guestDetails": [
{
"id": 0,
"forename": "string",
"surname": "string",
"email": "string",
"telephone": "string",
"specialInstructions": "string",
"completed": true,
"dietaryRequirements": [
{
"id": 0,
"name": "string",
"isRequired": true
}
]
}
]
}
]
}
I then have the following working typescript which maps it out to formbuilder:
this.myForm = this.fBuilder.group({
guestDetailsForm: this.fBuilder.array([])
});
this.httpService.getGuestDetails(this.eventId, this.passedIdValue)
.subscribe(data => {
this.fixturesArray = data.fixtures;
console.log(this.fixturesArray);
this.fixturesArray.forEach(fixturesArrayElement => {
this.guestDetailsArray = fixturesArrayElement.guestDetails;
this.guestDetailsArray.forEach(element => {
(<FormArray>this.myForm.get('guestDetailsForm')).push(this.fBuilder.group({
id: [element.id],
forename: [element.forename],
surname: [element.surname, Validators.required],
email: [element.email],
telephone: [element.telephone],
dietaryRequirements: [element.dietaryRequirements]
}));
});
});
},
error => alert(error),
() => console.log(""));
I can list out the forename, surname, email etc all fine but it won't display the text fields for the "dietaryRequirements" data in the following template. I assume it's to do with my inner *ngFor loop but nothing seems to work. Any help? :)
<div class="generalForm" formArrayName="guestDetailsForm">
<div *ngFor="let guest of myForm.controls.guestDetailsForm.controls; let i=index" [ngClass]="{'guestForm show' : viewingGuestId == i, 'guestForm hide' : viewingGuestId != i}">
<div [formGroupName]="i">
<input type="hidden" formControlName="id" />
<ol>
<li class="inputQuestion">
<label>Forename</label>
<input type="text" formControlName="forename" />
</li>
<li class="inputQuestion">
<label>Surname</label>
<input type="text" formControlName="surname" />
<div [hidden]="myForm.controls.guestDetailsForm.controls[i].controls.surname.valid" class="inlineError">Required
</div>
</li>
<li class="inputQuestion">
<label>Email</label>
<input type="text" formControlName="email" />
</li>
<li class="inputQuestion">
<label>Telephone</label>
<input type="text" formControlName="telephone" />
</li>
<li class="dietaryRequirementsQuestion" formArrayName="dietaryRequirements">
<div *ngFor="let meals of myForm.controls.guestDetailsForm.controls[i].controls.dietaryRequirements; let x=index">
<div [formGroupName]="x">
<input type="text" formControlName="name" />
</div>
</div>
</li>
</ol>
</div>
</div>
</div>
Upvotes: 1
Views: 3502
Reputation: 214017
I would create FormArray
instead of just array for dietaryRequirements
buildFormArrayOfGroupsFromArr(arr) {
return this.fBuilder.array(arr.map(x => this.fBuilder.group(x)));
}
...
dietaryRequirements: this.buildFormArrayOfGroupsFromArr(element.dietaryRequirements)
After that you write the following html:
<div *ngFor="let meals of myForm.controls.guestDetailsForm.controls[i].controls.dietaryRequirements.controls; let x=index">
<div [formArrayName]="x">
<input type="text" formControlName="name" />
</div>
</div>
You can also have a look at Plunker Example
Upvotes: 5