-3

I want to get the value of the radio button from each row as in the below screenshot from HTML to TypeScript.

enter image description here

        <form [formGroup]="feedbackForm" (ngSubmit)="submitData()">

            <table class="res-tbl">
                <thead style="background-color: #f6f9fc;">
                    <tr>
                        <th class="table-head"></th>
                    </tr>
                </thead>
                <tbody>
                    <tr class="skill-tr" *ngFor='let skill of skills; let i = index;'>
                            <td class="skill-td">
                                <b>{{skill.skillName}}<span>:</span></b>{{skill.description}}
                            </td>
                            <td>
                                <mat-radio-group  formControlName="resourceRating" name="ratingId{{i}}" >
                                    <span class="radio-span">0</span><mat-radio-button class="radio-btn"  value="0"></mat-radio-button>
                                    <span class="radio-span">1</span><mat-radio-button  class="radio-btn"  value="1"></mat-radio-button>
                                    <span class="radio-span">2</span><mat-radio-button  class="radio-btn"  value="2"></mat-radio-button>
                                    <span class="radio-span">3</span><mat-radio-button  class="radio-btn"  value="3"></mat-radio-button>
                                    <span class="radio-span">4</span><mat-radio-button  class="radio-btn"  value="4"></mat-radio-button>
                                </mat-radio-group>
                            </td>
                    </tr>
                </tbody>
            </table>
            <button>Submit</button>
        </form>

export class FeedbackFormComponent implements OnInit {
  resourceRating:[];
  ngOnInit(): void {
        this.ratings = this.ratingService.getAllRatings();
        console.log(this.ratings);
        this.skills = this.skillService.getAllSkills();
       
        this.feedbackForm = this.fb.group({
          applicantId:[''],
          positionId:[''],
          comments:[''],
          recommendation:[''],
          resourceRating:['']
            [this.fb.array([
             this.fb.group({
             skillId:[''],
             ratingId:['']
           })])]
        });      
  }
  submitData(){
    console.log('feedbackForm',this.feedbackForm);
    this.resFeedbackService.createResourceFeedback(this.feedbackForm.value);
  }
}
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Rose
  • 666
  • 6
  • 14
  • how is this different from your previous question? https://stackoverflow.com/questions/74917602/how-to-select-any-one-radio-button-in-a-table-row-and-this-should-be-for-all-oth – Jimmy Dec 28 '22 at 12:04
  • @Jimmy both are different. In that I was unable to select the radio buttons row wise. This question is getting the data to typescript. – Rose Dec 28 '22 at 12:08

1 Answers1

1

You need to add each line of the radio controls, so you get the current set value from it. You can do this when adding controls programmatically like this:

import { Component, VERSION } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = 'Angular ' + VERSION.major;
  feedbackForm: FormGroup;
  skills = [
    { skillName: 'First' },
    { skillName: 'Second' },
    { skillName: 'Third' },
  ];

  constructor(private fb: FormBuilder) {
    //this.feedbackForm = this.fb.group({
    //  radio0: [''],
    //  radio1: [''],
    //  radio2: [''],
    //  radio3: [''],
    //  radio4: [''],
    //});

    this.feedbackForm = this.fb.group({});

    for (let skillIndex = 0; skillIndex < this.skills.length; skillIndex++) {
      this.feedbackForm.addControl(
        'radio' + skillIndex.toString(),
        new FormControl(null)
      );
    }
  }

  submitData() {
    console.log(this.feedbackForm.value);
    // radio0: 2
    // radio1: 4
    // radio2: 1
  }
}

If you like the FormArray way, here it is:

  this.feedbackFormWithArray = this.fb.group({
      skills: fb.array(this.skills.map((t) => fb.control(t))),
    });

and HTML part

<p>Here with FormArray</p>
<form [formGroup]="feedbackFormWithArray" (ngSubmit)="submitData()">
  <table class="res-tbl">
    <tbody formArrayName="skills">
      <tr class="skill-tr" *ngFor="let skill of skills; let i = index">
        <ng-container *ngIf="i == i">
          <td class="table-data res-td" class="skill-td">
            <b>{{ skill.skillName }}</b>
          </td>
          <td>
            <input type="radio" formControlName="{{ i }}" [value]="1" />
          </td>
          <td>
            <input type="radio" formControlName="{{ i }}" [value]="2" />
          </td>
          <td>
            <input type="radio" formControlName="{{ i }}" [value]="3" />
          </td>
          <td>
            <input type="radio" formControlName="{{ i }}" [value]="4" />
          </td>
          <td>
            <input type="radio" formControlName="{{ i }}" [value]="5" />
          </td>
        </ng-container>
      </tr>
    </tbody>
  </table>
  <button>Submit</button>
</form>

I add the FormControls with its current name like in the working sample I answered before.

If you wanna use the Formbuilder so don't set skillId:['']. Do it instead like this: [skillId]:['']. This let you set the key name dynamically.

Example

let test1 = "Hello";
let test2 = "Bye";

let jsObject = {
  [test1]: "Rose!",
  [test2]: "Flo!"
}

// will create:

{
  Hello: "Rose!",
  Bye: "Flo!"
}

If you now submit the current result will be show.

enter image description here

I have updated the Stackblitz.

Last but not least: If you wanna have a result with objects (keys, value) use this:

submitData() {
    console.log(this.feedbackForm.value);
    // radio0: 2
    // radio1: 4
    // radio2: 1
    console.log(this.feedbackFormWithArray.value);
    const resultArray = [];
    for (let i = 0; i < this.skills.length; i++) {
      resultArray.push({
        skillId: this.skills[i].skillName,
        ratingId: this.feedbackFormWithArray.value['skills'][i],
      });
    }
    console.log(resultArray);
  }

enter image description here

Flo
  • 2,232
  • 2
  • 11
  • 18
  • how do I convert to this format on button click, resourceRating:[ { skillId:1, ratingId:2 }, { skillId:1, ratingId:3 } ] – Rose Dec 29 '22 at 05:21
  • 1
    Play with it, read the docs of FormArray - it will help. I have updated the Stackblitz and the answer – Flo Dec 29 '22 at 19:19
  • You can use a map to get the result instead use a loop: `const resultArray=this.feedbackFormWithArray.value.skills.map((x:any,index:number)=>({skillId:this.skills[index].skillName,rattingId:x}))` – Eliseo Dec 30 '22 at 08:49