Angular 2 ngModel and index with select element

Issue

I have a ng for loop like so

<template ngFor let-game [ngForOf]="(games)" let-index="index">
    <tr>
        <td>
            <select [(ngModel)]="selectedPrice" class="form-control" name="">
                <option *ngFor="let price of prices">{{price}}</option>
            </select>
        </td>
        <td>
    </tr>
</template>

Obviously, changing the price for one element changes it for all the other elements.

Here’s a fork of what I mean when you change one drop down it changes the other.
https://plnkr.co/edit/LVViSdlgmY56RnO8mAU4?p=preview

My question is: is there a way to utilize the index in the template element to only bind one selectedPrice for each element generated? So when I change the value of one dropdown value it doesn’t change them for all the others

I’ve tried certain syntaxes like [(ngModel)]=”selectedPrice[index]” which doesn’t do what I want meaning when I select a price, the selectedPrice[index] doesn’t actually contain a value. I have a few other ways that works but they’re hacky.

Solution

https://plnkr.co/edit/nOQ4ve9ee2A1TZjvrQBS?p=preview

//our root app component
import {Component, NgModule} from '@angular/core'
import {FormsModule} from '@angular/forms'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
      <tr *ngFor="let game of games; let i='index'">
        <td>
          {{game.name}} {{i}} {{game.price}}
        </td>
        <td>
            <select [(ngModel)]="games[i].price" class="form-control">
                <option *ngFor="let price of prices">{{price}}</option>
            </select>
        </td>
    </tr>
  `,
})
export class App {
  constructor() {}
  
  prices = ['40$', '30$', '20$'];
  games = [{name:'ge64'}, {name:'SM64'}];
  
}

@NgModule({
  imports: [ BrowserModule, FormsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

Answered By – chaoslaic

Answer Checked By – Robin (AngularFixing Admin)

Leave a Reply

Your email address will not be published.