Gowtham Raj J
Gowtham Raj J

Reputation: 967

Filtering out option values in Angular

I am trying a scenario in Angular 2, where we can select Super Powers for the Heroes in a dropdown which will be populated from a predefined list. And, I dont want any two superheros to have the same Super Power.

I have tried like below.

HTML:

<div class="form-group">

  <label>Hero One</label>
  <select (ngModelChange)="onChange($event)" class="form-control" name="sel">
    <option *ngFor="let pow of powers">
      <span *ngIf="check(pow)">{{pow}}</span>
    </option>
  </select>

</div>

<div class="form-group">

  <label>Hero Two</label>
  <select (ngModelChange)="onChange($event)" class="form-control" name="sel1">
    <option *ngFor="let pow of powers">
      <span *ngIf="check(pow)">{{pow}}</span>
    </option>
  </select>

</div>

<div class="form-group">

  <label>Hero Three</label>
  <select (ngModelChange)="onChange($event)" class="form-control" name="sel2">
    <option *ngFor="let pow of powers">
      <span *ngIf="check(pow)">{{pow}}</span>
    </option>
  </select>

</div>

Component.ts

export class HeroFormComponent {

  powers = ['Really Smart', 'Super Flexible', 'Super Hot', 'Weather Changer'];

  array = [];//storing the previously selected superpowers

  check(p) {
    var condition = this.array.length;

    for (var i = 0; i <= this.array.length; i++) {
      if (condition != 0) { //dont check if array is empty, just return true
        if (p === this.array[i]) { //return false if the superpower is present
          return false;
        }
        //return true, since power doesnt belong to anyother hero
        return true;
      }
      return true;
    }
  }

  onChange(p: string) {
    this.array.push(p);//push the selected values in this array;
    console.log(this.array);
  }

}

I guess I am not using the ngFor or ngIf properly, can you please point out what I am doing wrong, or how I could do it.

Upvotes: 0

Views: 48

Answers (1)

user4676340
user4676340

Reputation:

For my part, what I would do is something like this :

<select (change)="updatePowers(power, hero1)" [(ngModel)]="hero1.power">
    <option *ngFor="let pow of powers">...</option>
</select>

In your component :

powers = ['P1', 'P2', 'P3'];
hero1 = { name: 'Harold', power: undefined };

updatePowers(power: string, hero: any): void {
    if(hero.power) { this.powers.push(power); }
    hero.power = power;
    this.powers.slice(this.powers.indexOf(power), 1);
}

Basically, what you're doing is everytime you change the power, it is withdrawn from the array, and pushed into the hero. And, if you change the power of an hero, the power is put back into the array, then changed.

Since you have several heroes, what you could do is :

<ng-container *ngFor="let hero of heroes; let i = index">
    <h1>{{hero.name}}'s power </h1>
    <select (change)="updatePowers(power, hero)" [(ngModel)]="heroes[i].power">
        <option *ngFor="let pow of powers">...</option>
    </select>
</ng-container>

In your component :

powers = ['P1', 'P2', 'P3'];
heroes = [
    { name: 'Harold', power: undefined },
    { name: 'Kumar', power: undefined },
];

updatePowers(power: string, hero: any): void {
    if(hero.power) { this.powers.push(power); }
    hero.power = power;
    this.powers.slice(this.powers.indexOf(power), 1);
}

Upvotes: 1

Related Questions