Search code examples
angularngfor

Why are angular ngFor components sharing the same variables


I'm making a list of questions (question's name and yes/no checkboxes)

The problem is that when I click on the second question checkboxes, it still changes the ones from first component.

Here's my code:

Rendering the list of questions:

<div *ngFor="let question of questions">
  <app-question [question]="question"></app-question>
</div>

Each question:

<div class="question">
    {{question}}
    <div class="checkboxes">
        <label class="checkbox-label">
            <input class="checkbox" [(ngModel)]="checked.yes" (ngModelChange)="checkboxChanged('yes')" type="checkbox" id="check1"/>
            <label for="check1" class="custom-checkbox"></label>
        </label>
        <label class="checkbox-label">
            <input class="checkbox" [(ngModel)]="checked.no" (ngModelChange)="checkboxChanged('no')" type="checkbox" id="check2"/>
            <label for="check2" class="custom-checkbox"></label>
        </label>
    </div>
</div>

checkboxChanged(value): void {
    value === 'yes' ? this.checked["no"] = false : this.checked["yes"] = false;
}

Thanks

Edit: https://stackblitz.com/edit/angular-59bkvw

Solution: The problem was that my inputs and labels were sharing the same ids between components. I assigned an unique id like id="{{question}}" and it works. Thank you all for help.


Solution

  • So far I just found you have a single problem related to label for attribute and input id. The problem is that the id is not unique, all input elements have the same id. To solve this you have to generate the id dynamically:

    Pass the index of the element as prefix of the id :

    template

    <div class="question">
        {{question}}
        <div class="checkboxes">
            <label class="checkbox-label">
                <input class="checkbox" [(ngModel)]="checked.yes" (ngModelChange)="checkboxChanged('yes')" type="checkbox" [id]="index+'yes'"/>
                <label [for]="index+'yes'" class="custom-checkbox"></label>
            </label>
            <label class="checkbox-label">
                <input class="checkbox" [(ngModel)]="checked.no" (ngModelChange)="checkboxChanged('no')" type="checkbox" [id]="index+'no'"/>
                <label [for]="index+'no'" class="custom-checkbox"></label>
            </label>
        </div>
    </div>
    

    parent component

    <div *ngFor="let question of questions;let index = index">
      <app-question [question]="question" [index]="index"></app-question>
    </div>
    

    demo 🚀