Bug in angular binding.?

Issue

I have a component that is composed by a select and an input of type text, where the "select" I can use to select a description of an object and the input I can write the quantity to asignate to this. In my form I must be able to many objects and its quantity, So, every time i select one and I asign it a quantity, with a button save it in a object and showed it with a chip.

It’s happening that every time I do this, in the collection, all the items are replaced with the last one

Note: Angular CLI: Version 13.0.2 | npm 8.1.0

anotherWork = new workModel();
  anotherMaterial = new materialModel();
  anotherMaterialList = new Array<materialModel>();

  //FORM CONTROLS
  clientControl = new FormControl();
  descriptionControl = new FormControl();
  costControl = new FormControl();
  employeesControl = new FormControl();
  materialsControl = new FormControl();
  isFinishedControl = new FormControl();
  //[...
  //...
  //...]
    materialDescriptionChange(desc:string){
    this.anotherMaterial.description = desc;
  }

  materialQuantityChange(quan:string){
    this.anotherMaterial.quantity = parseFloat(quan);
  }

  addMaterial(id:string){
    this.anotherMaterial.id = id;
    this.anotherMaterialList.push(this.anotherMaterial);
    console.log(this.anotherMaterialList);
  }
<!--MATERIALES | CHIPS / SELECT / INPUT NUMBER / BUTTON-->
    <p>
        <mat-form-field  class="form-field" *ngIf="anotherMaterialList.length > 0">
            <mat-chip-list >
                <mat-chip *ngFor="let wmt of anotherMaterialList" >
                    {{wmt.description}} ({{wmt.quantity}})
                </mat-chip>
            </mat-chip-list>
        </mat-form-field>
    </p>
    <p *ngIf="materialList !== undefined">
        <!-- <mat-form-field appearance="legacy" class="form-field-material-select"> -->
        <mat-form-field appearance="legacy" class="form-field-material-select">
            <mat-label>Materiales</mat-label>
            <mat-select #ma [formControl]="materialsControl" (selectionChange)="materialDescriptionChange(ma.triggerValue)">
                <mat-select-trigger>
                    <span *ngIf="materialsControl.value?.length > 0">
                        {{ma.triggerValue}}
                    </span>
                </mat-select-trigger>
                <mat-option *ngFor="let m of materialList" [value]="m.id">
                    {{m.description}} ({{m.quantity}})
                </mat-option>
            </mat-select>
        </mat-form-field>
        <mat-form-field appearance="legacy" class="form-field-material-input">
            <mat-label>Cantidad</mat-label>
            <input #q matInput placeholder="Cantidad" type="number" (change)="materialQuantityChange(q.value)" >
        </mat-form-field>
        <a (click)="addMaterial(ma.value)" color="primary" mat-raised-button class="form-field-material-button">
            <mat-icon>add</mat-icon>
        </a> 
        
    </p>

Sequence in images

1 – First step, before add an object

2 – One object is added

3 – Add second object

4 – Add third object

5 – Evolution of the object in the browser inspector

Solution

You seem to be using the same object reference. Try creating a new one each time you want to add instead of reusing this.anotherMaterial:

addMaterial(id:string) {
  const material = new materialModel()
  material.id = id;
  material.description = this.anotherMaterial.description;
  material.quantity = this.anotherMaterial.quantity;
  this.anotherMaterialList.push(material);
  console.log(this.anotherMaterialList);
}

Answered By – Octavian M─ârculescu

Answer Checked By – David Marino (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.