Hey there, I'm facing a problem with creating a specific payload structure as shown in the example code snippet below. Everything was going well until I got stuck at the dynamic form part, and despite several attempts, I can't seem to figure it out. Any help would be greatly appreciated.
The issue lies in constructing the structure mentioned in the first block of code, particularly in the dataCollege field where I'm unable to save the dynamically changing array.
I've attempted placing FormControl in the HTML where I render the dynamic inputs, but it keeps throwing an error.
The payload structure I managed to put together involves the first three fields successfully. However, the last field, datosCole, is giving me trouble as it's dynamic based on the GradosCole field, which can have different values like initial (2 values), primary (3 values), and secondary (4 values).
{ name: Sara,
age: 14,
gradeCollege: Secondary,
dataCollege: {
course: "Maths",
schedule: "Afternoon",
section: "A",
teacher: "Mateo",
}
}
This is how my form is structured in HTML.
<div>
<form [formGroup]="form">
<!-- Name -->
<mat-form-field>
<input matInput type="text" placeholder="Name" [formControl]="name">
</mat-form-field>
<!-- Age -->
<mat-form-field>
<input matInput type="text" placeholder="Age" [formControl]="age">
</mat-form-field>
<!-- Grade -->
<mat-form-field>
<mat-label>Grade</mat-label>
<mat-select [formControl]="gradeCollege">
<mat-option *ngFor="let item of grades" [value]="item" (click)="getData(item)">
{{item}}
</mat-option>
</mat-select>
</mat-form-field>
<!-- dynamic data -->
<div *ngFor="let item of data; index as i" >
<mat-form-field>
<input matInput [type]="item.type" [placeholder]="item.label" [formControl]="dataCollege" >
</mat-form-field>
</div>
</form>
<div>
<button type="button" (click)="save()">Save</button>
</div>
</div>
This is the TypeScript file related to the form.
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators, AbstractControl } from '@angular/forms';
@Component({ selector: 'app-datos', templateUrl: './datos.component.html', styleUrls: ['./datos.component.scss'] }) export class DatosComponent implements OnInit {
public grades: any[] = ['initial','primary','secondary'];
public data: any[] = []
// Form
public form: FormGroup;
public name: AbstractControl;
public age: AbstractControl;
public gradeCollege: AbstractControl;
public dataCollege: AbstractControl;
constructor( protected fb: FormBuilder, ) {
}
ngOnInit() {
this.form = this.fb.group({
name: ['', Validators.compose([Validators.required])],
age: [''],
gradeCollege: ['', Validators.compose([Validators.required])],
dataCollege: ['']
});
this.name= this.form.get('name');
this.age = this.form.get('age');
this.gradeCollege = this.form.get('gradeCollege');
this.dataCollege = this.form.get('dataCollege'); }
getData (typeGrade: any) {
console.log(typeGrade);
if(typeGrade === 'initial'){
this.data = null
this.data = [
{type: 'text', label: 'course'},
{type: 'text', label: 'schedule'},
]
}
if(typeGrade === 'primary'){
this.data = null
this.data = [
{type: 'text', label: 'course'},
{type: 'text', label: 'schedule'},
{type: 'text', label: 'section'}
]
}
if(typeGrade === 'secondary'){
this.data= null
this.data = [
{type: 'text', label: 'course'},
{type: 'text', label: 'schedule'},
{type: 'text', label: 'section'},
{type: 'text', label: 'teacher'}
]
}
}
submit() {
const payload = {
name: this.name.value,
age: this.age.value,
gradeCollege: this.gradeCollege.value,
dataCollege: this.dataCollege.value,
};
console.log(payload)
}}
Error Message:
ERROR TypeError: ctx.save is not a function at ActionDialogComponent_Template_button_click_13_listener (template.html:34:36) at executeListenerWithErrorHandling (core.js:21860:1) at wrapListenerIn_markDirtyAndPreventDefault (core.js:21902:1) at HTMLButtonElement. (platform-browser.js:976:1) at ZoneDelegate.invokeTask (zone-evergreen.js:399:1) at Object.onInvokeTask (core.js:41686:1) at ZoneDelegate.invokeTask (zone-evergreen.js:398:1) at Zone.runTask (zone-evergreen.js:167:1) at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:480:1) at invokeTask (zone-evergreen.js:1621:1) defaultErrorLogger @ core.js:6241 handleError @ core.js:6294 handleError @ core.js:13881 executeListenerWithErrorHandling @ core.js:21863 wrapListenerIn_markDirtyAndPreventDefault @ core.js:21902 (anonymous) @ platform-browser.js:976 invokeTask @ zone-evergreen.js:399 onInvokeTask @ core.js:41686 invokeTask @ zone-evergreen.js:398 runTask @ zone-evergreen.js:167 invokeTask @ zone-evergreen.js:480 invokeTask @ zone-evergreen.js:1621 globalZoneAwareCallback @ zone-evergreen.js:1647