0

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'];
6
  • How does the this.data get its initial value in add-quanitity.component.ts? I suspect that the initial values of the colors are in one array instance and the colors contain reference to that instance. And as the quantity at one color is updated, the original array is updated and because of this all the colors get the same quantity value. Commented Apr 12, 2020 at 8:00
  • this.data is injected as @Inject(MAT_DIALOG_DATA) private data; Commented Apr 12, 2020 at 8:22
  • Thank you for the info. How does the origin of the injected data look like? I'm interested in how the default displayed data is created before it is injected in the component. Commented Apr 12, 2020 at 8:38
  • ok check the edit and thanks Commented Apr 12, 2020 at 9:01
  • 1
    Thank you, see my answer below. In the above code snippet this.selectedSizes and this.selectedColors are inversely. I assumed in my answer that this.selectedSizes =['XS', 'S']; and this.selectedColors = ['black', 'beige', 'blue'];. Commented Apr 12, 2020 at 9:31

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Since contents of the sizeQuantity are primitive types (string). You don't need a deep clone here. Using the array spread operator or slice method is enough.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.