Home > Blockchain >  Angular Array.push is pushing only last object in the array when the mat-checkbox is checked
Angular Array.push is pushing only last object in the array when the mat-checkbox is checked

Time:11-21

I have two components item-list and item . The item-list component display a list of items with checkboxes. I have been trying to push the items to a new Array when checked in the checkbox, but the Array holds only the last item when logged.

Below is the code I tried,

item-list.component.html

<div>
  <mat-form-field appearance="outline">
  <input matInput placeholder="Add a Task" (keyup.enter)="addTask()"autocomplete="off"[formControl]="nameControl"/>
  </mat-form-field>
</div>

<app-item
  [value]="value"
  *ngFor="let value of data; index as index"
  >
</app-item>

item.component.html

<div >
  <div >
  <mat-checkbox color="secondary" [(ngModel)]="IsChecked" (change)="onChange($event)"> 
  </mat-checkbox>
  </div>
</div>

<div >
 <div  [ngClass]="{ 'line-through': value.task }">
  {{ value.task | uppercase }}
 </div>
</div>

item.component.Ts

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

@Component({
  selector: 'app-item',
  templateUrl: './item.component.html',
  styleUrls: ['./item.component.scss'],
})

export class ItemComponent implements OnInit {

  @Input()
  value: any;

  IsChecked: boolean;
  public ArrayChecked: any[] = [];

  constructor() {
    this.IsChecked = false;
  }

  ngOnInit(): void {}

  onChange($event: any) {
     if ($event.checked) {
       this.ArrayChecked.push(this.value.task);

       console.log('the task is added', this.ArrayChecked);
     } 
     else console.log('the task is removed');
  }
  }

In the above code for component item, I tried pushing the items to a new array 'ArrayChecked' inside the onChange(), but when I log the result, the array holds only the last item that I checked. I would like to get the list of all items that were checked in the checkboxes.

Can someone help me fix my code , so all the checked items are inside 'ArrayChecked[]'. Thanks in advance!

CodePudding user response:

The problem here is that ArrayChecked is initialized in every item component, which means that each component is only going to push values to its own ArrayChecked variable. Therefore, only the value of the last checked checkbox is logged.

This can be fixed by initializing ArrayChecked in the item-list component instead of the item component. Then, the item component should fire an event when its checkbox's value changes with the item's task. You can then listen to this event in item-list and push the task to ArrayChecked.

item.component.ts

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

@Component({
  selector: 'app-item',
  templateUrl: './item.component.html',
  styleUrls: ['./item.component.scss'],
})

export class ItemComponent implements OnInit {

  @Input()
  value: any;

  // Emitted when the task is checked
  @Output()
  checkTask = new EventEmitter<any>;

  IsChecked: boolean;

  constructor() {
    this.IsChecked = false;
  }

  ngOnInit(): void {}

  onChange($event: any) {
     if ($event.checked) {
       // We now emit the checkTask event instead of directly pushing it to the array
       this.checkTask.emit(this.value.task);

       console.log('the task is added', this.ArrayChecked);
     } 
     else console.log('the task is removed');
  }
}

item-list.component.html

<app-item
  [value]="value"
  (checkTask)="addCheckedTask($event)"
  *ngFor="let value of data; index as index"
  >
</app-item>

item-list.component.ts

addCheckedTask($event: any): void {
  this.ArrayChecked.push($event);
}
  • Related