Search code examples
angularangular-reactive-formsangular-formsformarray

Dynamically load multiple dropdown in formarray in angular 6


I want to load two dropdown one dropdown is based on another dropdown.

I am using formarray to load the form values. In my actual scenario, first i am loading values in *ngfor loop with form data(formarray). below image shows my example scenario.

enter image description here

Img Brief: name, age, dob are like label field. only dropdowns are form.

first i am loading values in view using *ngFor then i am loading values using form array.

here on load it should load the dropdown values. if i am selecting first dropdown. it should change the second dropdown values. on load it self i am load the data in both the dropdown using service.

component.ts

this.wholedata.foreach({ x =>
 this.sampleservice.dropdown(x.firstdropdownvalue).subscribe({
  this.samplevalue = res;
  control.push({
   dropdownvalue1: x.firstdropdownvalue,
   dropdownvalue2: x.seconddropdownvalue
  })
 })
})

component.html

<div *ngFor="let data of datas">
 //formarray codes here placed
 <span>name: {{data.name}}</span>
 <span>age: {{data.age}}</span>
 <span>dob: {{data.dob}}</span>
 <span>
  <select formControlName="dropdownvalue1" (change)="changevalues($event)">
   <option *ngFor="let data of dropdownvalue">{{data.values}}</option>
  </select>
 </span>
 <span>
  <select formControlName="dropdownvalue2">
   <option *ngFor="let data of samplevalue">{{data.values}}</option>
  </select>
 </span>
 <button type="submit" (click)="submitValues()">
</div>

Currently samplevalue variable values loading to last *ngfor loop because the dynamic dropdown value is changing every array based on firstdropdown so i cant able to set the value.


Solution

  • you must use different list for each dropdown. So

    //you have a variable "options"
    options:any;
    
    //when you change one drop
    this.sampleservice.dropdown(x.firstdropdownvalue).subscribe({
      //Your response I supouse will be like ["one","two","three"..] (1)
      //or [{value:1,data:"one"},{value:2,data:"two"}...] (2)
      this.options[x.firsdropdownvalue]= res; //<--store the res in the object ...
      })
    
    //So, your dropdowns can be like
    <span>
      <select formControlName="dropdownvalue1" (change)="changevalues($event)">
      </select>
     </span>
     <span>
      <select formControlName="dropdownvalue2">
       <option *ngFor="let data of options[myForm.get('dropdownvalue1').value]">  
       <!--if your data is like (1) -->
       {{data}}   
       <!--if your data is like (2)
       {{data.values}}
        -->
       </option>
      </select>
     </span>
    

    Another option if your dropdowns don't have a large ammount of items is have some like

    options=[
       {value:1,data:"one",values:[{value:1,data:"one-one"},{value:2,data:"one-two"},..]},
       {value:2,data:"two",values:[{value:1,data:"two-one"},{value:2,data:"two-two"},..]},
       ...]
    
    // Then you can write
    <span>
      <select formControlName="dropdownvalue1" >
       <option *ngFor="let data of options" [ngValue]="data">{{data.data}}</option>
      </select>
     </span>
     <span>
      <select formControlName="dropdownvalue2">
       <option *ngFor="let data of myForm.get('dropdownvalue1').value.values">{{data.values}}</option>
      </select>
     </span>
    

    but be carefull! dropdownvalue if an object (the whole object of the selection)