Kevin Dias
Kevin Dias

Reputation: 1076

Update variable on *ngFor Angular

I have a *ngFor and I'm trying to update a {{subtotal}} label on click but it updates all of the items with same value. Same goes with {{quantity}}. There is a way to create local variables ? Heres my code

html

 <CardView class="cardStyle" *ngFor="let card of shoppingCart; let i = index;">

  <Label text="{{card?.product.productName}}" textWrap="false" class="product-title " row="1" col="0"></Label>

  <Label text="Quantity:{{quantity}}" textWrap="true" col="1" row="2" class="product-quantia" ></Label>

  <Label text="subtotal:{{subtotal}}" textWrap="true" col="1" row="2" class="product-quantia" ></Label>

  <Button text="&#xf056;" class="item-share-shop-save" (tap)="increase(card, i)" ></Button>

 </CardView>

my ts component

 subtotalResult:any = null;
 quantity: any;

increase(card:any, id:number){

   card.quantity += 1;
   this.subtotalResult = card.quantity * card.unitPrice; 

}

Upvotes: 0

Views: 1705

Answers (2)

Adrita Sharma
Adrita Sharma

Reputation: 22203

Since you have quantity and subtotalResult as a global item, changing for 1 item is modifying all.

Make them array if each items.

Try like this:

HTML:

<Label text="Quantity:{{quantity[i]}}" textWrap="true" col="1" row="2" class="product-quantia" ></Label>

<Label text="subtotal:{{subtotal[i]}}" textWrap="true" col="1" row="2" class="product-quantia" ></Label>

Typescript:

 subtotalResult: any[] = [];

  increase(card: any, index: any) {

    card.quantity += 1;
    this.subtotalResult[index] = card.quantity * card.unitPrice;

  }

Forked stackbiltz

Upvotes: 2

Andrew Howard
Andrew Howard

Reputation: 3092

This sort of thing is better to do with a reactive form BUT since you have no input fields you can get away with keeping it a template driven form.

On the creation of "shoppingCart" I'm assuming from your api, you need to loop through each item in the array and ensure there is a value for quantity and subtotal to begin with ie quantity:0 and subtotal:0 for each item. Then the below template will work:

<CardView class="cardStyle" *ngFor="let card of shoppingCart; let i = index;">

  <Label text="{{card?.product.productName}}" textWrap="false" class="product-title " row="1" col="0"></Label>

  <Label text="Quantity:{{card?.quantity}}" textWrap="true" col="1" row="2" class="product-quantia" ></Label>

  <Label text="subtotal:{{card?.subtotal}}" textWrap="true" col="1" row="2" class="product-quantia" ></Label>

  <Button text="&#xf056;" class="item-share-shop-save" (tap)="increase(card, i)" ></Button>

 </CardView>

Then in your increase function:

increase(card: any, index: any) {

    shoppingCart[index].quantity += 1;
    shoppingCart[index].subtotal = card.subtotal * card.quantity 

  }

You always need to update "shoppingCart" because before you were just updating a reference which isn't going to do anything since your template is based on "shoppingCart".

Upvotes: 2

Related Questions