0

I have two multiselect dropdowns as given below. If I choose

  • First dropdown :"ASIA" then Second dropdown should populate values: "India" and "UAE"
  • First dropdown :"ASIA" and "EUROPE" then Second dropdown should populate values: "India", "UAE" and "Germany"

I have tried the below code and the values are not populating in second dropdown when I select value form first. Second dropdown is empty always.

First multiselect dropdown :-

<p-multiSelect (onChange)="updateSecondDropdown($event)" [options]="regions" [(ngModel)]="regionValues" optionLabel="name" optionValue="name" defaultLabel="Select Regions"></p-multiSelect>

Second multiselect dropdown :-

<p-multiSelect [options]="countries" [(ngModel)]="countryValues" optionLabel="name" optionValue="name" defaultLabel="Select Countries"></p-multiSelect>

Typescript code :-

countries:any[]=[];

regions:any[]=[
  {id:1, name:"ASIA"},
  {id:2, name:"EUROPE"},
  {id:3, name:"NORTH AMERICA"},
  {id:4, name:"SOUTH AMERICA"},
]


countriesMapping:any[]=[
  {id:1, region:"ASIA", name:"India"},
  {id:2, region:"ASIA", name:"UAE"},
  {id:3, region:"NORTH AMERICA", name:"United States"},
  {id:4, region:"NORTH AMERICA", name:"Canada"},
  {id:5, region:"SOUTH AMERICA", name:"Mexico"},
  {id:6, region:"EUROPE", name:"Germany"}
]


updateSecondDropdown(event){
  this.countries=[];
  let selectedRegions = event.values;
  let selectedRegionNames = selectedRegions.map(o => o.name);
  selectedRegionNames.forEach((region) => {
   this.countriesMapping.forEach((country, index) => {
    if(country.region===region)
       this.countries.push(this.countriesMapping[index]);
   });
  });
}

I am using PrimeNg version: 8.0.0

sujai
  • 23
  • 1
  • 4

2 Answers2

1

There are several problems in your updateSecondDropdown function. Basically, you can change it to the following code:

updateSecondDropdown(event) {
    const selectedRegions = event.value;
    this.countries = this.countriesMapping.filter((country) => selectedRegions.includes(country.region));
}

The problems are:

  1. the list of selections on the event parameter are in the event member, not events.
  2. No need to map to the list of selected regions using o => o.name since you already get a list of names.

Final note:

This is not exactly an error but a tip. Whenever possible, use the proper array function for the job. It will make your code much simpler and easier to read. If you need to select certain items from a list of items, use the filter function. If you need to check if an item exists in a list of items, use the includes function.

The forEach function is is useful for many tasks but is not always the right tool.

Other functions of note:

  • some to check if at least one item in the list fits a criteria, returns boolean
  • every to check if all items in the least fit a criteria, returns boolean

There are others and I recommend you go over them to have them in the back of your mind so you'll know to look for them if the need arises.

Shai
  • 3,659
  • 2
  • 13
  • 26
  • I have updated method like this and it worked. updateSecondDropdown(event) { const selectedRegions = event.value; this.countries = this.countriesMapping.filter((country) => {return selectedRegions.some(region => region.name===country.region)}); } – sujai Jan 17 '22 at 06:46
  • Thank you for tip – sujai Jan 17 '22 at 06:52
  • My answer is better than what you posted, seems strange... – Shai Jan 17 '22 at 07:28
  • but your code didn't return expected result. – sujai Jan 18 '22 at 10:17
0

This solved my problem

updateSecondDropdown(event) { 
   const selectedRegions = event.value; this.countries = 
   this.countries = this.countriesMapping.filter((country) => {
     return selectedRegions.some(region => region.name===country.region)
   }); 
} 
sujai
  • 23
  • 1
  • 4