Jan
Jan

Reputation: 79

Angular - boolean value doesn't change

I'm facing issue with my app. I'm trying to create a list of checkboxes, when the checkbox is clicked the value should be true and when clicked again the value should be false. Simple.

Here is my html

  <li *ngFor="let checkbox of checkboxSelect">
      <div class="checkbox-style">
          <input type="checkbox" name ="{{checkbox.inputName}}" 
                [checked]="checkbox.name"
                (change)="checkbox.name= !checkbox.name"/>
             <div class="state">
                 <label>{{checkbox.label}}</label>
             </div>
      </div>
  </li>

Here is my component.ts

showFirstName = true;
showLastName = true;

checkboxSelect: any[] = [{
        label: 'First name',
        name: this.showFirstName,
        inputName: 'showFirstName'
    }, {
        label: 'Last name',
        name: this.showLastName,
        inputName: 'showLastName'

    },
];

Everything is working except my 'name' value doesn't change to true/false when clicked.

On the other hand when I put that straight to html without *ngFor it's working

  <li>
      <div class="checkbox-style">
          <input type="checkbox" name = "firstName"
                [checked]="showFirstName"
                (change)="showFirstName = !showFirstName"/>
             <div class="state">
                 <label>First Name</label>
             </div>
      </div>
  </li>

I wasn't so clear, my goal is to display divs depend on true/false

 <div *ngIf="showFirstName" scope="col">First name</div>
<div *ngIf="showLastName" scope="col">Second name</div>

But it doesn't change at all.

Does anyone have an idea what's wrong with my code?

Upvotes: 1

Views: 3765

Answers (3)

Barremian
Barremian

Reputation: 31125

Based on your comment, you are trying to use variables showFirstName and showLastName that aren't modified by the event handler to show/hide strings First Name and Last Name. To make the value binding persist between two variables, you could make them objects. Objects are usually passed by reference in Javascript. Try the following

Controller

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  showFirstName = { status: true };
  showLastName = { status: true };

  checkboxSelect: any[] = [{
    label: 'First name',
    name: this.showFirstName,
    inputName: 'showFirstName'
  }, {
    label: 'Last name',
    name: this.showLastName,
    inputName: 'showLastName'

  }, ];

  checkStatus() {
    console.log(this.checkboxSelect[0].name, this.checkboxSelect[1].name);
  }
}

Template

<li *ngFor="let checkbox of checkboxSelect">
  <div class="checkbox-style">
    <input type="checkbox" name="{{checkbox.inputName}}" [checked]="checkbox.name.status"
      (change)="checkbox.name.status = !checkbox.name.status; checkStatus()" />
    <div class="state">
      <label>{{checkbox.label}}</label>
    </div>
  </div>
</li>

<table>
  <th *ngIf="showFirstName.status" scope="col">First Name</th>
  <th *ngIf="showLastName.status" scope="col">Last Name</th>
</table>

Note: Using object reference to control the state of variables could get very tangled later in development. Better way would be to think of a different structure.

Working example: Stackblitz

Upvotes: 2

Metalgear
Metalgear

Reputation: 3457

Why don't you use Angular ngModel? Then you don't need to define change handler.

<li *ngFor="let checkbox of checkboxSelect">
      <div class="checkbox-style">
          <input type="checkbox" name ="{{checkbox.inputName}}" 
                [(ngModel)] ="checkbox.name"/>
             <div class="state">
                 <label>{{checkbox.label}}</label>
             </div>
      </div>
  </li>

Upvotes: 0

Aakash Garg
Aakash Garg

Reputation: 10979

Change your html to :-

<li *ngFor="let checkbox of checkboxSelect">
      <div class="checkbox-style">
          <input type="checkbox" [name] ="checkbox.inputName" 
                [checked]="checkbox.name"
                (change)="checkbox.name = !checkbox.name"/>
             <div class="state">
                 <label>{{checkbox.label}}</label>
             </div>
      </div>
  </li>

Upvotes: 0

Related Questions