0

I want to have a filter based on active-states from available checkboxes.

First everything should gets displayed, after a filter is selected, in this case a selection of hero names should only display heroes which contains atleast the name.

The interesting part is that: If I try to change the value back to the "full"-object it is not taking the complete object but an altered version of that.

I do not know what is happening there. Because I only initialized the full-object in the constructor of the app. With full-object I mean fullHeroes.

App.Component.ts :

import { Component, OnInit } from '@angular/core';

interface Hero {
    name: string;
}

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})
export class AppComponent {
  readonly fullHeroes: Hero[] = [];
  heroes: Hero[] = [];

  constructor() {
    this.heroes.push(
        { name: 'Bob' }, { name: 'Alice' }, { name: 'Mallory' }
    );
    this.fullHeroes = this.heroes.slice(0);
}

filter(name, checked) {
    if (checked) {
        for (let i = 0; i <= this.heroes.length; i++) {
            let found = false;
            const currentHero = this.heroes[i];
            if (currentHero && currentHero.name === name) {
                found = true;
            }
            if (found) {
                this.heroes.splice(i, 1);
            }
        }
    } else {
        this.heroes = [];
        this.heroes = this.fullHeroes;
    }
    return;
  }
}

App.component.html :

   <div class="container">
    <h1>World of Heroes</h1>
    <p>Filter your Heroes based on names!</p>

    <div class="filter">
      <form #heroForm="ngForm">

        <fieldset>
          <legend>Choose the names</legend>
          <div class="form-check" *ngFor="let hero of heroes">
            <label class="form-check-label">
                <input  class="form-check-input" type="checkbox" [name]="hero.name" (change)="filter($event.target.name, $event.target.checked)"> {{hero.name}}
            </label>
          </div>
        </fieldset>

      </form>
    </div>

    <hr>
  <h2>Results:</h2>

    <div class="row result-list">
      <div class="col-md-4 hero" *ngFor="let hero of heroes">
        <h3>Name: {{hero.name}}</h3>
      </div>
    </div>
  </div>
1

3 Answers 3

2

If you want to make a clone for the array this.fullHeroes into the array this.heroes, use:

this.heroes = JSON.parse(JSON.stringify(this.fullHeroes));

This way you will do a full copy of the array this.fullHeroes into this.heroes one, and then changes in this.heroes will not affect the other array.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much this solved my first problem. However it seems like just using this.heroes = JSON.parse(JSON.stringify(this.fullHeroes)); doesn't solve my logical problem with getting the correct results based on the selected checkboxes.
this is an answer for Angular cloned array gets changed automatically if it helped you then accept the answer that it can help other peoples. For the other problem you have, you can ask a new more specific question for that, that way you can get more help.
0
this.heroes = this.fullHeroes

After you execute that line, every time you mutate heroes, you also mutate fullHeroes, since they both refer to the same array. You need to make a copy of fullHeroes.

Note that you're abusing map() where you should be using forEach(). And you're using a loop where you could use some().

1 Comment

Thank you for the answer. I'm using forEach instead of map and using slice to create a real copy of the fullHeroes. However that doesn't solve my logical problem with displaying the correct result based on the selected checkboxes. Is there a simpler alternative way to get that thing done?
0

You can use the TypeScript spread operator to clone the array:

const a1 = [1, 2, 3, 4, 5, 6];
const a2 = [...a1];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.