'ERROR Error: Cannot find control with name: 'educationDetails'
I am trying to implement Form Array in custom multi-step form using Angular-12.
Component:
export class ProfileEditComponent implements OnInit {
isLinear = true;
isLoading = false;
isSubmitted = false;
multistepForm!: FormGroup;
step: any = 1;
constructor(
private fb: FormBuilder
) {}
ngOnInit(): void {
this.buildForm();
}
onFormSubmit() {
this.step = this.step + 1;
}
previous() {
this.step = this.step - 1;
}
buildForm() {
this.multistepForm = this.fb.group({
// multistepDetails: new FormGroup({
personalDetails: new FormGroup({
first_name: new FormControl('', [Validators.required, Validators.maxLength(50)]),
last_name: new FormControl('', [Validators.required, Validators.maxLength(50)]),
other_name: new FormControl('', [Validators.maxLength(50)]),
}),
educations: this.fb.array([
this.createEducation()
])
});
}
createEducation() {
return this.fb.group({
educationDetails: new FormGroup({
city: new FormControl('', Validators.minLength(3)),
country: new FormControl('', Validators.minLength(3))
}),
})
}
}
HTML:
<form [formGroup]="multistepForm" (ngSubmit)="onFormSubmit()">
<div class="card-body" *ngIf="step == 1" formGroupName="personalDetails">
<h4>Personal Details</h4>
<hr>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-12 col-md-4">
<div class="form-group">
<label for="name">First Name:<span style="color:red;">*</span></label>
<input type="text" formControlName="first_name" placeholder="First Name" class="form-control" />
</div>
</div>
<div class="col-12 col-md-4">
<div class="form-group">
<label for="name">Other Name:</label>
<input type="text" formControlName="other_name" placeholder="Other Name" class="form-control" />
</div>
</div>
<div class="col-12 col-md-4">
<div class="form-group">
<label for="name">Last Name:<span style="color:red;">*</span></label>
<input type="text" formControlName="last_name" placeholder="last Name" class="form-control" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card-body" *ngIf="step == 2" formGroupName="educationDetails">
<h4>Education Details</h4>
<hr>
</div>
<div class="card-body" *ngIf="step == 3">
<h4>Review</h4>
<hr>
</div>
<div class="card-footer">
<button type="submit" class="btn bg-navy margins" *ngIf="step != 1" (click)="previous()">Previous</button>
<button type="submit" class="btn btn-primary" *ngIf="step != 3">Next</button>
<button type="submit" class="btn btn-success" *ngIf="step == 3">Submit</button>
</div>
</form>
Whenever I click on Next button to take me to Education, I got this error:
ERROR Error: Cannot find control with name: 'educationDetails' at _throwError (forms.js:1721) at setUpFormContainer (forms.js:1694) at FormGroupDirective._setUpFormContainer (forms.js:5338)
How do I resolve this?
Thanks
Solution 1:[1]
In step 2 you have not given educations formArray reference in HTML. So to get those Formarray or Forgroup[] you need to create one property on your ProfileEditComponent as below:
get educations(): FormGroup[] {
return (<FormArray>this.multistepForm.controls['educations']).controls as FormGroup[];
}
This will return you all the educations in the form of FormGroup[]. Now you have to use this to bind your controls on HTML. So in your HTML you need to change your step 2 this way:
<div class="card-body" *ngIf="step == 2">
<div *ngFor="let item of educations; index as i">
<div [formGroup]="item">
<div formGroupName="educationDetails">
<h4>Education Details</h4>
<hr>
<div>
<label for="city">City:</label>
<input type="text" formControlName="city">
</div>
<div>
<label for="country">Country:</label>
<input type="text" formControlName="country">
</div>
</div>
</div>
</div>
</div>
Solution 2:[2]
My case is using other's share component, and the share component use zone and setTimeout to build the formGroup and formArray. So the life cycle was not in my expected.
When data binding or even you use console.log to print, the formGroup and formControl is truly exist. But it always return ERROR Error: Cannot find control with name: 'formControl'. That's how the zone and setTimeout make an impact.
Finally, I set *ngIf="formGroup" in all the tag which has [FormGroup] =[formGroup]. So whatever formGroup is exist or not, it works fine.
<!-- which has [formGroup]="fg", add *ngIf="fg" -->
<div [formGroup]="fg" ***ngIf="fg"**>...</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Devang Patel |
Solution 2 |