Hyena
Hyena

Reputation: 49

Why is Angular overwriting the original variable?

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);

Upvotes: 1

Views: 693

Answers (3)

Quentin
Quentin

Reputation: 1933

Calling .slice on the original array clones the array :

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

Clone an Array

Upvotes: 2

Barremian
Barremian

Reputation: 31105

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));
}

Upvotes: 1

Ashish
Ashish

Reputation: 14697

Try this

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

For explanation please refer : Cloning an array in Javascript/Typescript

Upvotes: 2

Related Questions