Wojciech Abacki
Wojciech Abacki

Reputation: 251

NgFor display last element

I have array of objects

[0: {yplace: 11, xrow: 4}1: {yplace: 12, xrow: 4}2: {yplace: 13, xrow: 4} ]

<div class="row-place" *ngFor="let seat of reservation.seats; let i = index" >
  {{seat.xrow}} <input [(ngModel)]="seat.xrow" name="row" type="number" min="0" class="place form-control signup-row">
  {{seat.yplace}} <input [(ngModel)]="seat.yplace" name="place" type="number" min="0" class="place form-control signup-row">
</div>

And in html i have 3 inputs, all bind only last element from array?

but when i use {{seat.xrow}} and {{seat.yplace}} that display fine that i expected

How do two-way data binding with input tag. Each input has unique index from array not last element?

edit: and i have that

  reservation: ReservationAdminDto = {
    seats: [],
    email: '',
    phoneNr: ''
 };

ReservationAdminDto.model.ts has a form:

export class ReservationAdminDto {
  email: string;
  phoneNr: string;
  seats: SeatDto[];
}

SeatDto.model.ts

export class SeatDto {

  xrow: number;
  yplace: number;

  constructor (
    xrow: number,
    yplace: number,
  ) {
    this.xrow = xrow;
    this.yplace = yplace;
  }
}

Upvotes: 4

Views: 3887

Answers (2)

Martin Parenteau
Martin Parenteau

Reputation: 73731

Your *ngFor loop is probably inside a form tag. Since the input elements in the loop have the same name, they display the last value in the array, as shown in this stackblitz.

To bind the correct item values, make sure that the input names are unique by appending the loop index to each name (see this stackblitz):

<div class="row-place" *ngFor="let seat of reservation.seats; let i = index" >
  <input [(ngModel)]="seat.xrow" [name]="'row'+i" type="number" min="0" class="place form-control signup-row">
  <input [(ngModel)]="seat.yplace" [name]="'place'+i" type="number" min="0" class="place form-control signup-row">
</div>

Upvotes: 9

user4676340
user4676340

Reputation:

The issue is a tracking issue : [(ngModel)] creates new variables, and it can't bind to object properties properly. use a custom track by function to get a grip on it :

<div class="row-place" *ngFor="let seat of reservation.seats; let i = index; trackBy: customTB">
customTB(index, item) {
  return `${index}-${item.xrow}-${item.yplace}`
}

Upvotes: 0

Related Questions