Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to setvalue in formbuilder array

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>
like image 732
Mahalo Bankupu Avatar asked Nov 01 '16 09:11

Mahalo Bankupu


2 Answers

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;
} 
like image 151
shehzad lakhani Avatar answered Nov 11 '22 06:11

shehzad lakhani


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 :)

like image 2
Magnus Gudmundsson Avatar answered Nov 11 '22 07:11

Magnus Gudmundsson