Srdan
Srdan

Reputation: 229

Angular 9 update object in array of objects

As the title says I need to update one value in array.

<div *ngFor="let item of data; let i = index" >
  <div class="full-w" fxLayout='row' fxLayoutAlign='start center' fxLayoutGap='12px'>
    <span class="title">Color: </span>
    <span>{{item.color}}</span>
  </div>
  <mat-divider class="full-w"> </mat-divider>

  <div *ngFor="let e of item.sizeQuantity; let j = index" fxLayout='row' fxLayoutAlign='space-between center'
    fxLayoutGap='12px'>
    <span class="title">Size: </span>
    <span class="size">{{e.size}}</span>
    <mat-form-field>
      <input matInput type="number" placeholder="Quantity" [value]="e.quantity" #quantity />
    </mat-form-field>

    <button mat-button (click)="updateQuantity(quantity.value, item, i, j)">Add</button>
  </div>
</div>

and this is the initial data

enter image description here

and when I enter the data in one field, e.g. under black>xs, it changes on beige>xs too (if there is blue>xs or more it gets updated)

enter image description here

enter image description here

I tried several approaches but it keeps updating values at every position

  updateQuantity(value, item, ind, j) {

    this.data.forEach(e => {
      if (e.color == item.color) {
        e.sizeQuantity[j].quantity = parseInt(value);
      }
    })
  }

Or like this

  updateQuantity(value, item, ind, j) {
    this.data.find(e => e.color == item.color).sizeQuantity[j].quantity = parseInt(value); 

  }

Am I missing something?

//EDIT:

Data is created like this:

       let quantity = [];
        let sizeQuantity = [];

        this.selectedSizes.forEach(e => {
          sizeQuantity.push({ size: e, quantity: 0 })
        })

        this.selectedColors.forEach(e => {
          quantity.push({ color: e, sizeQuantity })

        })

        this.dialog.open(AddQuantityComponent, {
          data: quantity
        })

where sizes and colors arrays are dynamically created based on user selection:

this.selectedColors  = ['black', 'beige', 'blue'];
this.selectedSizes = ['XS', 'S'];

Upvotes: 0

Views: 4632

Answers (1)

Milan Tenk
Milan Tenk

Reputation: 2715

The quantity values are updated in each color, because they share the same sizeQuantity instance. The problem roots at this method

this.selectedColors.forEach(e => {
  quantity.push({ color: e, sizeQuantity })
})

Here a deep copy has to be created from the sizeQuantity, this means that following could be used:

this.selectedColors.forEach(e => {
  let sq = JSON.parse(JSON.stringify(sizeQuantity));
  quantity.push({ color: e, sizeQuantity: sq });
});

It is tricky that JSON serialize/deserialize is used for creating deep copy, but this is the easiest and most backward compatible method. For further details about creating a deep copy check out this stackoverflow conversation.

Upvotes: 1

Related Questions