0

I have a service where there is a cards array, which I looped thru in list-cards.html component template with *ngFor="let card of this.cardService.cards. This cards array has a list of object created from API call, and it's rendered at app initialization as home page.

How do I filter that cards array from the card.service.ts in non-mutating way?

For now, it's like this (mutating way):
card.service.ts file:

this.cards = this.cards.filter((e: any) => e.id !== id);

If I create a new array variable, to filter it in non-mutating way, like in this example from: https://lorenstewart.me/2017/01/22/javascript-array-methods-mutating-vs-non-mutating/

const arr1 = ['a', 'b', 'c', 'd', 'e'];

const arr2 = arr1.filter(a => a !== 'e'); // ['a', 'b', 'c', 'd']

then it can't be looped any more with above *ngFor declaration, because it's another array now, right!?

So, I came up to solution based on above example, where I've declared two array variables in the card.service.ts file:

cards: any[];
// new array to avoid array mutation
newCards: any[] = [];

In the list-cards.ts component in ngOnInit directive I've declared:

// to render initial data from the array
this.cardService.newCards = this.cardService.cards;

and at list-cards.html now I declared *ngFor="let card of this.cardService.newCards,

and at last, filter method in card.service.ts looks as follow:

this.newCards = [...this.cards].filter((e: any) => e.id !== id);

I am not really sure if my code accomplish the goal of non-mutating array??

I just find out that on delete action click, only once item is filtered. Every other delete click action is not filtered, but cards are deleted from db.

If I loop thru cards array, not newCards array with *ngFor="let card of this.cardService.cards" everything work just fine, but then array is mutated!?

Srdjan Milic
  • 328
  • 2
  • 14
  • 1
    `const arr2 = [...this.cards].filter(.....` – Keith Jun 15 '20 at 21:06
  • Does this answer your question? [Copy array by value](https://stackoverflow.com/questions/7486085/copy-array-by-value) – Heretic Monkey Jun 15 '20 at 21:30
  • You current code `this.cards = this.cards.filter(...);` already does what you want: it does not mutate the array. It creates a new array, which you then assign to the same variable. – ConnorsFan Jun 16 '20 at 00:12

1 Answers1

-1

JFYI, spread operator to create a copy of the array.

Example:

Copy an array

const arr = [1, 2, 3];

const arr2 = [...arr]; // like arr.slice()

arr2.push(4);
//  arr2 becomes [1, 2, 3, 4]
//  arr remains unaffected

Now in your case, I think you are on the right track. You would need to keep the original array safe and use another array to assign the filtered data which you need to bind in html.

Manish
  • 6,106
  • 19
  • 64
  • 90