[Fixed] Why is Angular overwriting the original variable?

Issue

I’m new to Angular, so hopefully this will make perfect sense to someone out there, but I’ve been at it for hours now.

export class QuizComponent implements OnInit {

  originalArray: IArray[] = [];
  tempArray: IArray[] = [];

  constructor(
    private fetchService: FetchService
  ) {}

  ngOnInit(): void {
    this.originalArray = this.fetchService.getData();
    this.tempArray = this.originalArray
  }
  onWin() {
    this.tempArray = this.originalArray;
  }
}

export class FetchService {
  constructor() {}

  nameArray: IArray[] = [
    {name: 'John'},
    {name: 'Jade'},
    {name: 'Dave'},
    {name: 'Rose'},
  ];

  getData() {
    return this.nameArray;
  }
}

What I would like to happen is that once someone wins, I can restore the tempArray to the originalArray. Unfortunately, every time tempArray get modified (using angular drag and drop), originalArray also gets modified – I logged originalArray when I made a change to make sure that was the case – so there’s no original state to restore to.

I’ve tried a lot of different variants of returning getData, and different ways of setting the variables – in and out of ngOnInit() and the constructor, directly in the QuizComponent, making it readonly etc.

Any direction would be dearly appreciated.

EDIT: Someone answered, then immediately deleted their answer, which was what I ended up going with. Whoever you are, thank you! And big thanks to everyone else helping me with this.

this.tempArray = Object.assign([], this.originalArray);

Solution

There isn’t much information to go on. But one thing that stands out is you’re making a shallow copy of the arrays. Note that in Javascript copies of arrays (or objects for that matter) as passed around as references. So any change to one variable will also naturally affect it’s shallow copies.

One quick workaround for a deep copy is to convert to string and back

ngOnInit(): void {
  this.originalArray = JSON.parse(JSON.stringify(this.fetchService.getData()));
  this.tempArray = JSON.parse(JSON.stringify(this.originalArray));
}

onWin() {
  this.tempArray = JSON.parse(JSON.stringify(this.originalArray));
}

Leave a Reply

(*) Required, Your email will not be published