Search code examples
angularselectangular-reactive-forms

Get option text value of all dropdowns in Angular reactive form


After a lot of search, and after trying Copilot, didn't found the answer.

I have a dynamic reactive form with 1 to n dropdowns. When changing any dropdown, I need to loop all existing dropdowns and get the text value (not the value), to verify some rules.

The data structure is like:

[
{
   id: 1,
   options: [
     {
       key: 100,
       value: "First"
     },
     {
       key: 101,
       value: "Second"
     },
     {
       key: 102,
       value: "Third"
     }
   ]
},
{
   id: 2,
   options: [
     {
       key: 100,
       value: "First"
     },
     {
       key: 101,
       value: "Second"
     },
     {
       key: 102,
       value: "Third"
     }
   ]
},...
]

I build the form this way:

form!: FormGroup;

ngOnInit() {
    const group: any = {};

    this.myArrayOfDataObjects.forEach(data => {
      group[data.id] = new FormControl('');
    });

    this.form = new FormGroup(group);
}

HTML (the dropdown part):

@for (data of myArrayOfDataObjects; track data.id) {
    <mat-select
      [id]="data.id"
      [formControlName]="data.id"
      (selectionChange)="changeValue($event)"
    >
      <mat-option>--</mat-option>
      @for (opt of vs.options; track opt.key) {
        <mat-option [value]="opt.key">{{ opt.value }}</mat-option>
      }
    </mat-select>
}

And, when changing any value, I know I can loop it all values:

changeValue() {
    for (const [key, value] of Object.entries(this.form.value)) {
        console.log(`${key}: ${value}`);
        // Also
        console.log(this.form.get(key)?.value);
    }
}

But don't know how to get the text value. Any ideas? Stackblitz example here


Solution

  • We can use this.form.value to access the values! I also use <form [formGroup]="form">...</form> to define the form on which the elements belong to, and a button to fetch the values!

    import { Component } from '@angular/core';
    import {
      FormControl,
      FormGroup,
      FormsModule,
      ReactiveFormsModule,
    } from '@angular/forms';
    import { MatInputModule } from '@angular/material/input';
    import { MatSelectModule } from '@angular/material/select';
    import { MatFormFieldModule } from '@angular/material/form-field';
    import { CommonModule } from '@angular/common';
    
    /**
     * @title Basic select
     */
    @Component({
      selector: 'select-overview-example',
      template: `
      <form [formGroup]="form">
        @for (data of myArrayOfDataObjects; track data.id) {
          <mat-select
            [id]="data.id.toString()"
            [formControlName]="data.id"
            (selectionChange)="changeValue($event)"
          >
            <mat-option>--</mat-option>
            @for (opt of data.options; track opt.key) {
              <mat-option [value]="opt.key">{{ opt.value }}</mat-option>
            }
          </mat-select>
        }
      </form>
    <br/>
      <button (click)="getValue()">Click to get the values</button>
    <br/>
    
      {{form.value | json}}
      `,
      standalone: true,
      imports: [
        MatFormFieldModule,
        MatSelectModule,
        MatInputModule,
        FormsModule,
        ReactiveFormsModule,
        CommonModule,
      ],
    })
    export class SelectOverviewExample {
      myArrayOfDataObjects = [
        {
          id: 1,
          options: [
            {
              key: 100,
              value: 'First',
            },
            {
              key: 101,
              value: 'Second',
            },
            {
              key: 102,
              value: 'Third',
            },
          ],
        },
        {
          id: 2,
          options: [
            {
              key: 104,
              value: 'First',
            },
            {
              key: 105,
              value: 'Second',
            },
            {
              key: 106,
              value: 'Third',
            },
          ],
        },
      ];
    
      form!: FormGroup;
    
      ngOnInit() {
        const group: any = {};
    
        this.myArrayOfDataObjects.forEach((data) => {
          group[data.id] = new FormControl('');
        });
    
        this.form = new FormGroup(group);
      }
    
      changeValue(event: any) {
        Object.entries(this.form.value).forEach(
          ([key, value]: any, index: number) => {
            console.log(`${key}: ${JSON.stringify(value)}`);
            // Also
            const dValue = this.form.get(key)?.value;
            const finalValue = this.myArrayOfDataObjects?.[index]?.options?.find(
              (x: any) => x.key === value
            )?.value;
            console.log('only value:', finalValue);
          }
        );
      }
    
      getValue() {
        console.log(this.form.value);
      }
    }
    

    Stackblitz Demo