Home > Software design >  How to display the filtered object array on button click in Angular?
How to display the filtered object array on button click in Angular?

Time:11-29

I have been trying to develop a todo list project. I have two components itemList and item in my project. The item List component gets the input value for the todolist and displays it in the item component.

enter image description here

enter image description here

The item list component holds an array of objects, with a checkbox. What I have been trying to do, is to set a button filter for this list based on the checkbox. So when the button (display checked) is clicked, the list should display only the items that were checked in the checkbox.

I have attached the stackblitz code here: code available here

Below are the codes I tried:

item-component.html

<div >
<div
  
  [style.backgroundColor]="IsChecked ? 'grey' : '#ff6165'"
>
  <div>
    <mat-checkbox
      color="secondary"
      [(ngModel)]="IsChecked"
      (change)="onChange($event, value.task)"
    ></mat-checkbox>
  </div>
</div>

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

<div >
  <Matbutton mat-icon-button [matMenuTriggerFor]="menu">
    <mat-icon>more_vert</mat-icon>
  </Matbutton>
  <mat-menu #menu="matMenu">
    <button mat-menu-item (click)="removeTask($event)">
      <mat-icon >delete</mat-icon>
      <span>remove</span>
    </button>
  </mat-menu>
 </div>
</div> 
</div>

item.component.ts

export class ItemComponent implements OnInit {
  @Input()
  value: any;
  IsChecked: boolean;
  @Output()
  checkTask = new EventEmitter<any>();

  constructor() {
   this.IsChecked = false;
  }

  ngOnInit(): void {}


  onChange($event: any, name: any) {
   if ($event.checked) {
    this.checkTask.emit(this.value);
   } 
   else {
    this.removeCheck.emit(this.value)
    console.log('the task is removed');
   }
   }
  }

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>
<button (click)="displaylist()">Display Checked</button>
</div>

<ng-container *ngIf="filteredData$ | async as data">
<div
  cdkDropList
  
  (cdkDropListDropped)="drop($event, data)"
 >
<app-item
  [value]="value"
  *ngFor="let value of data; index as index"
  (inputDataChange)="removeTask(data, index)"
  (checkTask)="addCheckedTask($event, data)"
  (removeCheck)="removeCheckedTask($event,data)"

  cdkDrag
 >
</app-item>
</div>
</ng-container>

item-list.component.ts

 public arrayChecked: TaskType[] = [];

 addCheckedTask($event: any, data: any): void {
    this.arrayChecked.push($event);
    console.log('the task is added', this.arrayChecked);
 }

 displaylist(){
    const selectList$ = this.arrayChecked.map((checked, index) => checked ? 
    this.arrayChecked[index] : null).filter(value => value !== null);
    console.log("DisplayChecked",selectList$);
 }

 removeCheckedTask($event:any, data:any){
    const index = this.arrayChecked.findIndex(list => list.task);
    this.arrayChecked.splice(index, 1);
    console.log(this.arrayChecked);
 }

In the above code, the item-list component has a button "Display checked". This is where I tried to make a array of objects that were checked using a function. The log shows , the array holds only the checked items, but I dont know how to display only the checked items inside the component. I have also attached the stackblitz link above. Can someone show me how to display only the checked items in the list when the button is clicked. Thank you in advance!

CodePudding user response:

Since your list is driven by filteredData$ in the template, you need to update it with selectList$, that holds all the checked items.

item-list.component.ts:

displaylist(){
     const selectList$ = this.arrayChecked.map((checked, index) => checked ? this.arrayChecked[index] : null)
    .filter(value => value !== null);
    console.log("DisplayChecked",selectList$);

    // add this code
    if (selectList$) {
      this.filteredData$ = new Observable((subscriber) => {
        subscriber.next(selectList$ as TaskType[])
      });
    }
}

Stackblitz Demo

I have also added a 'Reset' button in To Do section of the Demo, so you can test the case of undoing 'Display Checked'. For this, I created a re-usable function initlist(), called it in ngOnInit() and attached to 'Reset' button's click event.

item-list.component.ts:

export class ItemListComponent implements OnInit {

  ...
  ...
  ...


  ngOnInit(): void {
    this.initlist();
  }

  ...
  ...

  initlist() {
    if (this.initialData$) {
      this.filteredData$ = combineLatest([
        this._homeService.searchData$,
        this.initialData$,
      ]).pipe(
        map(([searchValue, dailyList]) =>
          this._filterData(searchValue, dailyList)
        )
      );
    }
  }
}
  • Related