Caroline Teulery
Caroline Teulery

Reputation: 45

Only increment one item inside ngFor (Angular 2)

I'm trying to create a little shopping cart with ionic 2 and angular 2. For now, here is my code :

Front :

 <ion-card *ngFor="let person of people;let i = index" >

        <ion-card-header>{{person.name.first}} {{person.name.last}} {{i}}</ion-card-header>

        <ion-item>
        <ion-icon name="add-circle" (click)="incrementQty(i)" item-right></ion-icon>
        <ion-input type="number" min="1" [value]="qty" [(ngModel)]="qty"></ion-input>
        <ion-icon name="remove-circle"(click)="decrementQty(i)" item-right></ion-icon>
        </ion-item>
</ion-card>

.ts file :

incrementQty(index:number){
  console.log(this.people[index]);
  this.qty += 1;
}

My problem is that I only want to increment the clicked element, not all of them !

I'm new to angular 2 and don't know how to manage this problem, so thank you for your help !

Upvotes: 0

Views: 3271

Answers (2)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657118

You need a qty value per person, currently you have only one for the entire component.

qty:number[];


loadPeople(){ 
  this.peopleService.load()
  .then(data => { 
    this.people = data; 
    this.qty = new Array(this.people.length);
  }); 
}

incrementQty(index:number){
  console.log(this.people[index]);
  this.qty[index] += 1;
}
<ion-card *ngFor="let person of people;let i = index" >

        <ion-card-header>{{person.name.first}} {{person.name.last}} {{i}}</ion-card-header>

        <ion-item>
        <ion-icon name="add-circle" (click)="incrementQty(i)" item-right></ion-icon>
        <ion-input type="number" min="1" [value]="qty[i]" [(ngModel)]="qty[i]"></ion-input>
        <ion-icon name="remove-circle"(click)="decrementQty(i)" item-right></ion-icon>
        </ion-item>
</ion-card>

Upvotes: 1

Santanu Biswas
Santanu Biswas

Reputation: 4787

I can think of two possible solutions:

Option-1

Let qty be a property of the person object and in your incrementQty method do this.people[index].qty += 1

private quantities: number[];

constructor() {
  this.people = this.people.map(person => {
     person['qty'] = 0;
     return person
  });
}

incrementQty(index:number){
  this.people[index].qty += 1;
}

HTML:

<ion-card *ngFor="let person of people;let i = index" >

        <ion-card-header>{{person.name.first}} {{person.name.last}} {{i}}</ion-card-header>

        <ion-item>
        <ion-icon name="add-circle" (click)="incrementQty(i)" item-right></ion-icon>
        <ion-input type="number" min="1" [value]="person.qty" [(ngModel)]="person.qty"></ion-input>
        <ion-icon name="remove-circle"(click)="decrementQty(i)" item-right></ion-icon>
        </ion-item>
</ion-card>

Option-2

Create an array of qty in the (maybe in the constructor) component code. The size of the array should be same as the size of the people array. Set initial values to 0. In your code, you can increment the quantity in the array at index same as index of person in people array.

private quantities: number[];

constructor() {
  this.quantities = new Array(this.people.length);
  this.quantities= this.quantities.map((el: any) => 0);
}

incrementQty(index:number){
  this.quantities[index] += 1;
}

HTML:

<ion-card *ngFor="let person of people;let i = index" >

        <ion-card-header>{{person.name.first}} {{person.name.last}} {{i}}</ion-card-header>

        <ion-item>
        <ion-icon name="add-circle" (click)="incrementQty(i)" item-right></ion-icon>
        <ion-input type="number" min="1" [value]="quantities[i]" [(ngModel)]="quantities[i]"></ion-input>
        <ion-icon name="remove-circle"(click)="decrementQty(i)" item-right></ion-icon>
        </ion-item>
</ion-card>

Upvotes: 2

Related Questions