0

I have a parent component with a reactive form including controls and a from group.

When choosing playerType dropdown I am adding to the fromGroup a formArray. The new form array will consits of 2 form groups or 3 depending on playerType.

Let say a user created a Player and choose playerType = "Mage", then I need to create a new "skills" formArray inside configuration formGroup.

Example below - base form:

public PlayerForm: PlayerFormGroup = this.fb.group(
    {
        id: null,
        name: null, 
        life: 100, 
        playerType: null,
        configuration: this.fb.group({
            playerAllies: null
            weapons: []
        })
    
) as PlayerFormGroup;

enter image description here

So now the player is created and new formArray is added.

Look like this:

  public PlayerForm: PlayerFormGroup = this.fb.group(
    {
        id: 1,
        name: UserMage1, 
        life: 100, 
        playerType: 2,
        configuration: this.fb.group({
            playerAllies: null
            weapons: [],
            skills: [mageSkills:[name:'', power:null, duration:0]]
        })
    
) as PlayerFormGroup;

-> It will look like:

id:1,

name: 'UserMage1',

life:100,

playerType: 2,

configuration:

[playerAllies: null,

weapons:[],

skills:mageSkills:[0:{ name: 'someName', power:'fire', duration:2 }, 1:{ name: 'teleport', power:'dark', duration:4 }] ]

enter image description here

So, I am having trouble on saving the Power and Duration.

Code:

Parent TS:

public getSkillDetails(skillName: string): SkillView{
  // from child-component-configure, on selecting get the selected skill name and pass 
  // it to child-component-view-Skill-details (using event emitter)
    return this.skillsArray.find((skill) => skill.name === skillName);
  }

Parent HTML:

<parent-component [formGroup]="PlayerForm" (submit)="playerForm.submit()">
      <mat-form-field>
        <mat-label>"Name"</mat-label>
        <input matInput formControlName="name">        
      </mat-form-field>
     
     <mat-form-field>
        <mat-label>"Life"</mat-label>
        <input matInput formControlName="life">        
      </mat-form-field>

    <mat-form-field>
        <mat-label>"Type"</mat-label>
        <input matInput formControlName="playerType">        
      </mat-form-field>

  <child-component-configure *ngIf="PlayerForm.control.playerType.value != null"
      [selectedSkill] = "skill"> (event emitter to pass selected skill name)
  </child-component-configure>

 <child-component-view-Skill-details [skillSelected] = "skill"> 
 </child-component-view-Skill-details [value]="getSkillDetails(this.selectedSkill)">
</parent-component>

Child-HTML:

<child-component-configure>
  <mat-form-field>
        <mat-label>"Allies"</mat-label>
        <input matInput formControlName="allies">        
   </mat-form-field>

 <mat-form-field>
        <mat-label>"Weapons"</mat-label>
        <input matInput formControlName="weapons">        
  </mat-form-field>

 <mat-form-field>
        <mat-label>"Weapons"</mat-label>
        <input matInput formControlName="weapons">        
  </mat-form-field>

 </child-component-configure>

Child-view-Skill-details-HTML:

     <child-component-view-Skill-details> 
         <div>
          <label>Power</label>
          <input formControlName="power">        
         </div>

         <div class="slider-text">
           <label>Duration</label>
           <mat-slider
            [max]="10"
            [min]="1"
            [step]="1"
            [(ngModel)]="value.timeout">
          </mat-slider>
    </div>
    </child-component-view-Skill-details>
  • Diagram demonstrating the separation of components and the uses of form controls:

enter image description here

Above code is an abstraction of the code.

I want to find a way to change duration and power and update/pass the values to base form.

Currently creating is ok but, on updating Power and Timeout are always null and 0.

If there is any more info I can provide please let me know.

1 Answer 1

1

if you want update formGroup, you can do like this

your code

public PlayerForm: PlayerFormGroup = this.fb.group(
    {
        id: 1,
        name: UserMage1, 
        life: 100, 
        playerType: 2,
        configuration: this.fb.group({
            playerAllies: null
            weapons: [],
            skills: [mageSkills:[name:'', power:null, duration:0]]
        })
    
) as PlayerFormGroup;

this works!

PlayerForm = this.fb.group({
  id: new FormControl(1),
  name: new FormControl(userMage1),
  life: new FormControl(100),
  playerType: new FormControl(2),
  configuration: new FormGroup({
    playerAllies: new FormControl(null),
    weapons: new FormArray([]),
    skills: new FormArray([
      new FormGroup({
        mageSkills: new FormArray([new FormGroup({
          name: new FormControl(''),
          power: new FormControl(null),
          duration: new FormControl(0)
        })])
      })
    ])
  })
})

updatePlayer() {
  const form = this.PlayerForm.get('configuration').get('skills') as FormArray;
  const formArr = form.controls[0].get('mageSkills') as FormArray;
  const formMageSkills = formArr.controls[0]
  formMageSkills.get('name').setValue('someName')
  formMageSkills.get('power').setValue('fire')
  formMageSkills.get('duration').setValue(2)
}
1
  • The above is working! I have created an eventEmitter and I am using it to update the Player! Thanks your answer helped me.
    – MMario
    Commented Dec 13, 2023 at 10:01

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.