I have a problem about set array value to formBuilder.array. In the formBuilder that not array it can use this way to setValue but in formBuilder.array I can't do it. I try set value to formbuilder 'listServiceFeature' and 'listservicefeature' but it's not set value either way.
ts
listServiceFeature: any = ['m1', 'm2']
contentFormValidate(): void {
this.contentForm = this.formBuilder.group({
'listservicefeature': this.formBuilder.array([
this.formBuilder.group({
listServiceFeature: ['', [Validators.required]
});
]),
});
this.contentForm.controls['listservicefeature'].setValue(this.listServiceFeature);
}
addServiceFeature() {
const control = <FormArray>this.contentForm.controls['listservicefeature'];
control.push(this.initServiceFeature());
}
removeServiceFeature(i: number) {
const control = <FormArray>this.contentForm.controls['listservicefeature'];
control.removeAt(i);
}
html
<div formArrayName="listservicefeature">
<div class="form-group" *ngFor="let servicefeature of contentForm.controls.listservicefeature.controls; let i=index">
<label for="Service">Features {{i+1}}</label>
<div class="input-group" [formGroupName]="i">
<input type="text" class="form-control" formControlName="listServiceFeature">
<template [ngIf]="i == 0">
<span class="input-group-btn">
<button (click)="addServiceFeature()" class="btn btn-default" type="button">
<span class="lnr lnr-plus-circle icon-orange-gable-buttom"></span>
</button>
</span>
</template>
<template [ngIf]="i > 0">
<span class="input-group-btn">
<button (click)="removeServiceFeature(i)" class="btn btn-default" type="button">
<span class="lnr lnr-trash icon-orange-gable-buttom"></span>
</button>
</span>
</template>
</div>
</div>
</div>
Angular 6 FormBuilder array Example
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-team></app-team>
`
})
export class AppComponent {
}
employee.ts
export class Employee {
empId = '';
empName = '';
skill = '';
}
department.ts
export class Department {
deptHead = '';
deptName = '';
}
team.ts
import { Employee } from './employee';
import { Department } from './department';
export class Team {
teamName = '';
teamManager = '';
teamDept : Department;
employees: Employee[];
}
team-data.ts
import { Team } from './team';
export const ALL_TEAMS: Team[] = [
{
"teamName":"Java Team",
"teamManager":"Yogi",
"teamDept":{
"deptHead":"Modi",
"deptName":"M Commerce"
},
"employees":[
{
"empId":"101",
"empName":"Harish",
"skill":"Java"
},
{
"empId":"111",
"empName":"Mohit",
"skill":"Angular"
}
]
}
];
export const ALL_SKILLS = [
{name: 'Java', displayName: 'Java'},
{name: 'Angular', displayName: 'Angular'},
{name: 'Dot Net', displayName: 'Dot Net'}
];
team-management.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Team } from './team';
import { ALL_TEAMS, ALL_SKILLS } from './team-data';
@Injectable()
export class TeamManagementService {
getSkills() {
return Observable.of(ALL_SKILLS);
}
getAllTeams(): Observable<Team[]> {
return Observable.of(ALL_TEAMS);
}
getTeamByName(name: string): Observable<Team> {
return this.getAllTeams()
.map(allTeams => allTeams.find(team => team.teamName === name));
}
saveTeam(team: Team) {
console.log('------------TEAM------------');
console.log('Team Name: '+ team.teamName);
console.log('Team Manager: '+ team.teamManager);
console.log('Dept Head: '+ team.teamDept.deptHead);
console.log('Dept Name: '+ team.teamDept.deptName);
console.log('----- Employee Detail -----');
for(let emp of team.employees) {
console.log('Emp Id: '+ emp.empId);
console.log('Emp Name: '+ emp.empName);
console.log('Emp Skill: '+ emp.skill);
console.log('-------------------');
}
}
}
team-management.component.ts
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, FormArray, Validators, FormBuilder } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { TeamManagementService } from './team-management.service';
import { Team } from './team';
import { Employee } from './employee';
import { Department } from './department';
@Component({
selector: 'app-team',
templateUrl: './team-management.component.html'
})
export class TeamManagementComponent implements OnInit {
teamForm:FormGroup;
formSubmitted = false;
allSkills: Observable<any[]>
constructor(
private formBuilder:FormBuilder,
private teamMngService: TeamManagementService) {
}
ngOnInit() {
this.allSkills = this.teamMngService.getSkills();
this.createTeamForm();
this.addEmployee();
}
createTeamForm(){
this.teamForm = this.formBuilder.group({
teamName: ['', Validators.required ],
teamManager: '',
teamDept: this.formBuilder.group(new Department()),
employees: this.formBuilder.array([])
});
}
get empFormArray(): FormArray{
return this.teamForm.get('employees') as FormArray;
}
addEmployee(){
let fg = this.formBuilder.group(new Employee());
this.empFormArray.push(fg);
}
deleteEmployee(idx: number) {
this.empFormArray.removeAt(idx);
}
loadTeam(name: string) {
this.teamMngService.getTeamByName(name)
.subscribe( team => {
this.createFormWithDefaultData(team);
});
}
createFormWithDefaultData(team: Team) {
//this.teamForm.patchValue(team);
this.teamForm.patchValue({
teamName: team.teamName,
teamManager: team.teamManager,
teamDept: team.teamDept
});
let employeeFormGroups = team.employees.map(employee => this.formBuilder.group(employee));
let employeeFormArray = this.formBuilder.array(employeeFormGroups);
this.teamForm.setControl('employees', employeeFormArray);
}
onFormSubmit() {
let data = JSON.stringify(this.teamForm.value);
console.log('-----Team in JSON Format-----');
console.log(data);
let team: Team = this.teamForm.value;
this.teamMngService.saveTeam(team);
this.formSubmitted = true;
this.teamForm.reset();
}
resetTeamForm() {
this.teamForm.reset({
teamName: 'Java Team',
teamManager: 'Yogi'
});
}
}
team-management.component.html
<h3>Create New Team
<button type="button" (click)="loadTeam('Java Team')" > Load Default Team </button>
<button type="button" (click)="resetTeamForm()"> Reset </button>
</h3>
<div *ngIf="formSubmitted && teamForm.pristine" class = "submitted"> Form submitted successfully. </div>
<div class="team">
<form [formGroup]="teamForm" (ngSubmit)="onFormSubmit()">
<p>Team Name : <input formControlName="teamName">
<br/><label *ngIf="teamForm.get('teamName').invalid && teamForm.get('teamName').dirty" class = "error"> Team name is required. </label>
</p>
<p>Team Manager : <input formControlName="teamManager"></p>
<b>Department :</b><br>
<div formGroupName="teamDept" class="department">
<p>Department Head : <input formControlName="deptHead"></p>
<p>Department Name : <input formControlName="deptName"></p>
</div>
<div class="all-emp">
<b> Employees in Team :</b><br><br>
<div formArrayName="employees">
<div *ngFor = "let emp of empFormArray.controls; let idx = index" [formGroupName]="idx" class="employee">
<p> <b>Employee : {{idx + 1}}</b> </p>
<p>Emp Id : <input formControlName="empId"></p>
<p>Emp Name : <input formControlName="empName"></p>
<p>Skill :
<select formControlName="skill">
<option *ngFor="let skill of allSkills | async" [ngValue]="skill.name">
{{ skill.displayName }}
</option>
</select>
</p>
<p><button type="button" (click)="deleteEmployee(idx)">Delete</button></p>
</div>
</div>
<button type="button" (click)="addEmployee()">Add More Employee</button>
</div> <br/>
<button [disabled]="teamForm.invalid">SUBMIT</button>
</form>
</div>
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { TeamManagementComponent } from './team-management.component';
import { TeamManagementService } from './team-management.service';
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule
],
declarations: [
AppComponent,
TeamManagementComponent
],
providers: [
TeamManagementService
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
styles.css
.employee {
border: 2px solid blue;
width: 275px;
}
.department {
border: 2px solid blue;
width: 275px;
}
.team {
border: 3px solid black;
width: 300px;
}
.all-emp {
border: 3px solid black;
width: 275px;
}
.error{
color: red;
}
.submitted{
color: green;
font-size: 20px;
}
It looks to me like what you want to do is to add a control to the formArray. Take a look at the documentation for reactive-forms
https://angular.io/guide/reactive-forms
quote:
Notice that you replace the previous FormArray with the FormGroup.setControl method, not with setValue. You're replacing a control, not the value of a control.
in the documentation they do like this: 1) Add a getter as shortcut to the formArray:
get listservicefeatures(): FormArray {
return this.contentform.get('listservicefeature') as FormArray;
};
2) create an add method that would look like this:
addServiceFeature() {
this.listservicefeatures.push(this.fb.group({newservicefeature: 'defaultvalue', [Validators.required]}));
}
also your inital declaration of the formArray should probably look like this:
this.contentForm = this.formBuilder.group({
'listservicefeature': this.formBuilder.array([]),
});
I hope this helps :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With