Skip to content
Advertisement

Change in one dropdown value is affecting other dropdowns

I have a add button which will keep on adding a div container which consists of two dropdowns. On selecting on dropdown we are setting other dropdown data.

When I click on add div it will add a second div with both dropdowns. But, change in one dropdown is affecting other dropdown.

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  private map = new Map<string, string[]>([
    ['Poland', ['Warszawa', 'Krakow']],
    ['USA', ['New York', 'Austin']],
  ]);
  filtersList: any = [{}];

  country: string;
  city: string;

  get countries(): string[] {
    return Array.from(this.map.keys());
  }

  get cities(): string[] | undefined {
    return this.map.get(this.country);
  }

  addFilter() {
    this.filtersList.push({});
  }

  removeFilter(index) {
    this.filtersList.splice(index, 1);
  }

  trackByIndex(index, item) {
    return index;
  }
}

app.component.html

<div *ngFor="let num of filtersList; let i = index; trackBy: trackByIndex">
  <select [(ngModel)]="country">
    <option *ngFor="let country of countries" [value]="country">
      {{ country }}
    </option>
  </select>

  <select *ngIf="country" [(ngModel)]="city" [value]="city">
    <option *ngFor="let city of cities">{{ city }}</option>
  </select>
  <button (click)="removeFilter()">Remove</button>
</div>
<button (click)="addFilter()">Add more filters</button>

After adding div, each dropdown should have respective selected values.

Advertisement

Answer

So, when I click on add div it will add a second div with both dropdowns. But, change in one dropdown is affecting other dropdown.

That’s because these two dropdowns share the same variable/storage. You need to give them separate storage. In this case, we create a list of object with selectedCountry and selectedCity.

app.component.ts

// import stuff here


type Filter = {
  selectedCountry: string;
  selectedCity: string;
};

@Component({
...
})
export class AppComponent {

  ...
  
  filterList: Filter[] = [];

  addFilter() {
    this.filterList.push({selectedCountry: '', selectedCity: ''});
  }

}

app.component.html

<div *ngFor="let filter of filterList">

  <select [(ngModel)]="filter.selectedCountry">
    <option *ngFor="let country of countries" [value]="country">
      {{ country }}
    </option>
  </select>

  <select *ngIf="country" [(ngModel)]="filter.selectedCity" [value]="city">
    <option *ngFor="let city of cities">{{ city }}</option>
  </select>

  <button (click)="removeFilter()">Remove</button>

</div>

<button (click)="addFilter()">Add more filters</button>
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement