I want to use some part of the angular reactive form will come from an ng-template. Seperating in different component will work fine with ngViewProviders. But I want to achieve it via ng-template.
<h1>Test Reactive Form</h1>
<form [formGroup]="form">
<ng-container
[ngTemplateOutlet]="formArray"
[ngTemplateOutletContext]="{formGroup:form, arrayName:test}"
></ng-container>
</form>
{{form.value | json}}
<ng-template #formArray let-formGroup="formGroup" let-arrayName="arrayName" >
<ng-container [formGroup]="formGroup">
<div formArray="arrayName">
<ng-container *ngFor="let t of arrayName.controls;let i = index;" [formGroupName]="i">
{{formGroup.value | json}}
<input type="text"/>
</ng-container>
</div>
</ng-container>
</ng-template>
`,
})
export class App {
name = 'Angular';
form;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
test: this.fb.array([]),
});
const test = this.fb.group({
name: 'Test name',
});
this.test.push(test);
const test_1 = this.fb.group({
name: 'test name 2',
});
this.test.push(test_1);
}
get test(): FormArray {
return this.form.get('test') as FormArray;
}
Getting erro like ERROR Error: Cannot find control with name: '0'
Stackbitz link: https://stackblitz.com/edit/angular-9jmcfq?file=src%2Fmain.ts
the attributes formGroupName
, formGroup
, formArray
and formArrayName
must have a proper HTML element defined, removed all ng-container
and replaced with div
.
For defining form array you should use formArrayName
, the name should match the label test
that you defined inside the formGroup({...}).
The input inside the for loop should have formControlName="name"
added.
<ng-template #formArray let-formGroup="formGroup" let-arrayName="arrayName" >
<div [formGroup]="formGroup">
<div formArrayName="test">
<div *ngFor="let t of arrayName.controls;let i = index;" [formGroupName]="i">
<input type="text" formControlName="name"/>
</div>
</div>
</div>
</ng-template>
import 'zone.js';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import {
FormArray,
FormBuilder,
FormsModule,
ReactiveFormsModule,
} from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [FormsModule, ReactiveFormsModule, CommonModule],
template: `
<h1>Test Reactive Form</h1>
<form [formGroup]="form">
<ng-container
[ngTemplateOutlet]="formArray"
[ngTemplateOutletContext]="{formGroup:form, arrayName:test}"
></ng-container>
</form>
{{form.value | json}}
<ng-template #formArray let-formGroup="formGroup" let-arrayName="arrayName" >
<div [formGroup]="formGroup">
<div formArrayName="test">
<div *ngFor="let t of arrayName.controls;let i = index;" [formGroupName]="i">
<input type="text" formControlName="name"/>
</div>
</div>
</div>
</ng-template>
`,
})
export class App {
name = 'Angular';
form;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
test: this.fb.array([]),
});
const test = this.fb.group({
name: 'Abhisek',
});
this.test.push(test);
const test_1 = this.fb.group({
name: 'Abhisek2',
});
this.test.push(test_1);
}
get test(): FormArray {
return this.form.get('test') as FormArray;
}
}
bootstrapApplication(App);