Home > Software design >  Typescript error removing an object from an array
Typescript error removing an object from an array

Time:12-23

In a project in angular I have a table with several elements and in each row there is a button that is used to delete the corresponding row. In the button I inserted an event that on click calls a function and passes the id of the object:

<button mat-flat-button (click)="removePhase(phase.id)">
   <span><mat-icon>close</mat-icon></span>
</button>

when pressed calls this function:

removePhase(id:number){
    console.log(this.phase) /*First log*/
    this.phase.forEach((element) => {
    if (element.id != id) {
      this.phaseRemove.push(element);
      }
    })
    this.phaseRemove.forEach((element, index) => {
      element.id = index;
    })
    this.phase = this.phaseRemove;
    this.dataSource = new MatTableDataSource(this.phase);
    console.log(this.phase) /*Second log*/
  }

this is the phase object:

[
    {
        "id": 0,
        "phaseName": "Phase 1"
    },
    {
        "id": 1,
        "phaseName": "Phase 2"
    },
    {
        "id": 2,
        "phaseName": "Phase 3"
    },
    {
        "id": 3,
        "phaseName": "Phase 4"
    }
]

when the function is launched the first time everything works normally, while when I launch it a second time it loops the first for. I entered two console logs to see what happens and in the first one I get this object (in this thing I pressed the button to delete the object with id 0):

[
    {
        "id": 0,
        "phaseName": "Phase 1",
    },
    {
        "id": 0,
        "phaseName": "Phase 2",
    },
    {
        "id": 1,
        "phaseName": "Phase 3",
    },
    {
        "id": 2,
        "phaseName": "Phase 4",
    }
]

and in the second log, I get the correct object instead:

[
    {
        "id": 0,
        "phaseName": "Phase 2",
    },
    {
        "id": 1,
        "phaseName": "Phase 3",
    },
    {
        "id": 2,
        "phaseName": "Phase 4",
    }
]

As you can see the console log of the first object also sets the id 0 to the second object, I think this is the infinite for loop error, but I don't know how to solve it. Thank you.

CodePudding user response:

removePhase(id:number){
    this.phaseRemove = [];
    console.log(this.phase) /*First log*/
    for(const element of this.phase) {
      if (element.id != id) {
        this.phaseRemove.push(element);
      }
    }
    for (let i=0 ; i< this.phaseRemove.length; i  ){
      this.phaseRemove[i].id = i;
    }
    this.phase = JSON.parse(JSON.stringify(this.phaseRemove));
    this.dataSource = new MatTableDataSource(this.phase);
    console.log(this.phase) /*Second log*/
}

The issue is caused because thereis a reference between this.phase and this.phaseRemove. They are a similar object which are pointing to one place inside the memory.

You should break their reference using the JSON.parse(JSON.stringify()). Then you will let them to be completely different objects.

CodePudding user response:

i think there is better way to remove the item from this collection

work with the object refrence to delete any of those clicked items \

removePhase(id:number){ 
   // but becareful here we override the main list again then we add it to the data source  
    this.phase = this.phase.filter(item => item.id !== id)
    this.dataSource = new MatTableDataSource(this.phase);
    console.log(this.phase) // will have your items without the clicked one 
}
  • Related