Search code examples
angularradio-buttonformarrayform-controlpatchvalue

How to patchValue to radio button in angular?


How to patchValue to radio button in angular? I have to patch rating for particular skill, how to do this in typescript?

HTML Code

 <tbody formArrayName="skills">
                <tr class="skill-tr" *ngFor="let skill of skills; let i = index">
                    <td class="table-data res-td" class="skill-td">
                        <b value="skill.skillId">{{skill.skillName}}<span>:</span></b>{{skill.skillDescription}}
                    </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>
                </tr>
              </tbody>

Cosole log for rating based skill: Image

Image

I want to patch radio button rating value based on skill.

UI Screenshot

UI Screenshot

Response which I have to patch to the radio button I copied the response from the console,

(6) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
Object0
rating: {createdBy: 0, lastUpdatedBy: 0, ratingId: 1, rating: 5, ratingName: 'Outstanding'}
skill: {createdBy: 0, lastUpdatedBy: 0, skillId: 9, skillName: 'Overall Evaluation', skillDescription: 'Developer'}

Object1
rating: {createdBy: 0, lastUpdatedBy: 0, ratingId: 1, rating: 5, ratingName: 'Outstanding'}
skill: {createdBy: 0, lastUpdatedBy: 0, skillId: 8, skillName: 'Organizational Fit', skillDescription: 'Developer'}

Object2
rating: {createdBy: 0, lastUpdatedBy: 0, ratingId: 1, rating: 5, ratingName: 'Outstanding'}
skill: {createdBy: 0, lastUpdatedBy: 0, skillId: 7, skillName: 'Flexibility', skillDescription: 'Developer'}

Object3
rating: {createdBy: 0, lastUpdatedBy: 0, ratingId: 1, rating: 5, ratingName: 'Outstanding'}
skill: {createdBy: 0, lastUpdatedBy: 0, skillId: 6, skillName: 'Interpersonal/Communication Skills', skillDescription: 'Developer'}

Object4
rating: 
{createdBy: 0, lastUpdatedBy: 0, ratingId: 1, rating: 5, ratingName: 'Outstanding'}
skill: {createdBy: 0, lastUpdatedBy: 0, skillId: 5, skillName: 'Motivation/Initiative', skillDescription: 'Developer'}

Object
5
rating: {createdBy: 0, lastUpdatedBy: 0, ratingId: 2, rating: 4, ratingName: 'Excellent-exceeds requirements'}
skill: {createdBy: 0, lastUpdatedBy: 0, skillId: 4, skillName: 'Professional Impression', skillDescription: 'Developer'}
 
Object6
rating: {createdBy: 0, lastUpdatedBy: 0, ratingId: 3, rating: 3, ratingName: 'Competent-acceptable proficiency'}
skill: {createdBy: 0, lastUpdatedBy: 0, skillId: 3, skillName: 'Relevant Background/Special Skill Set', skillDescription: 'Developer'}

Solution

  • It's like another FormControl or FormGroup

    As you have a FormArray of FormControls you need "feed" with an array of values

    //create an array of values
    const data=this.yourObject.map(x=>x.ratting.ratting)
    
    //use patchValue
    this.form.controls.skills.patchValue(data)
    

    Well, yourObject looks like not ordered so we are going to create an array of values "ordered"

    const data:number[]=[];
    this.myObject.forEach((x:any,index:number)=>{
        data[x.skillId-1]=x[index].ratting.ratting
    })
    //or using reduce
    const data=this.myObject.reduce((a:number[],b:any)=>{
        a[x.skillId-1]=b.ratting.ratting
        return a
    },[])
    

    Some point about your code

    1. It's would prefer use [formControlName]="i"better than formControlName="{{i}}"

    2. Always it's better iterate over formArray.controls and use the index to show the "labels"

         <tr class="skill-tr" *ngFor="let skill of
                      skillsArray.controls; let i = index">
           ...
           <b [value]="skills[i].skillId">{{skills[i].skillName}}<span>:</span>
         </tr>
      

      Where you have a getter

      get skillsArray()
      {
         return this.form.controls.skills as FormArray
      }
      

    NOTE: when we make a patchValue in a FormArray we need take account that the FormArray and the data have the same length