When ever we enter text in the filter section, we need to call an API to get the relevant output list and update this into multiselect results.

Here I tried onFilter event to call the API, I got the API result but the result list not getting updated in the multiselect DOM. I can not override the default filter result. When I do next keypress then the filtering happening based on my last result.

html code:

<p-multiSelect
          class="add-more-permission-modal__container__filter"
          [options]="permissions"
          [(ngModel)]="selectedPermission"
          [autofocusFilter]="true"
          optionLabel="label"
          styleClass="es-multi-select es-multi-select--filter es-multi-select--no-scroll w-full"
          [resetFilterOnHide]="true"
          placeholder="Select permission of any department"
          appendTo="body"
          (onFilter)="onKeyUp($event)"
        ></p-multiSelect>

ts code:

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  EventEmitter,
  Input,
  OnInit,
  Output
} from '@angular/core';
import { AddAdminUserPermission } from 'src/app/compliance/interface';
import { debounceTime, distinctUntilChanged, filter, Subject } from 'rxjs';
import { AdminUserApiService } from '../../../../services/admin-user-api.service';

@Component({
  selector: 'es-admin-add-more-permission',
  templateUrl: './add-more-permission.component.html',
  styleUrls: ['./add-more-permission.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AddMorePermissionComponent implements OnInit {

  public filterInput$ = new Subject<string>();
  public permissions: AddAdminUserPermission[] = [];
  selectedPermission: AddAdminUserPermission[];

  constructor(
    private adminUserService: AdminUserApiService,
    private cdr: ChangeDetectorRef
  ) {}

  ngOnInit(): void {
    this.filterInput$
      .pipe(
        debounceTime(300),
        distinctUntilChanged(),
        filter((query) => query?.length >= 3)
      )
      .subscribe((filterValue) => {
        console.log(filterValue);

        this.adminUserService.filterPermission(filterValue).subscribe((res) => {
          this.permissions = res;
          console.log('searched permissions: ', this.permissions);
          this.cdr.detectChanges();
        });
      });
  }

  onKeyUp($event: any) {
    this.filterInput$.next($event.filter);
  }
}


service code:

@Injectable({
  providedIn: 'root'
})
export class AdminUserApiService {
  constructor() {}
  filterPermission(filterPermissionParams: string) {
    console.log('filter permission called');

    const permissions: PermissionDto[] = [
      {
        id: 101,
        name: 'Permission 101',
        departmentResponse: {
          id: 2,
          name: 'Engineering Department'
        }
      },
      {
        id: 102,
        name: 'Permission 102',
        departmentResponse: {
          id: 2,
          name: 'Engineering Department'
        }
      },
      {
        id: 103,
        name: 'Permission 103',
        departmentResponse: {
          id: 2,
          name: 'Engineering Department'
        }
      },
      {
        id: 104,
        name: 'Permission 104',
        departmentResponse: {
          id: 3,
          name: 'Bank Department'
        }
      },
      {
        id: 105,
        name: 'Permission 105',
        departmentResponse: {
          id: 3,
          name: 'Bank Department'
        }
      }
    ];
    const permissions2: PermissionDto[] = [
      {
        id: 201,
        name: 'Permission 201',
        departmentResponse: {
          id: 5,
          name: 'Engineering Department 2'
        }
      },
      {
        id: 202,
        name: 'Permission 202',
        departmentResponse: {
          id: 5,
          name: 'Engineering Department 2'
        }
      },
      {
        id: 205,
        name: 'Permission 205',
        departmentResponse: {
          id: 8,
          name: 'Bank Department 2'
        }
      }
    ];
    if (filterPermissionParams === 'cat') {
      return of(permissions);
    } else if (filterPermissionParams === 'cats') {
      return of(permissions2);
    } else {
      return of([]);
    }
  }
}

1

There are 1 best solutions below

1
Eliseo On

It's looks like work, the only is filter the value when you received the new values

this.filterInput$
  .pipe(
    debounceTime(300),
    distinctUntilChanged(),
    filter((query) => query?.length >= 3),
  )
  .subscribe((filterValue) => {
    this.adminUserService.filterPermission(filterValue).subscribe((res) => {
      this.permissions = res.map(x=>({label:x,value:x}));
      //here you filter the "selectedPermisions"
      if (this.selectedPermission)
          this.selectedPermission=this.selectedPermission
                                    .filter(x=>res.includes(x.label))

      //this.cdr.detectChanges(); <--it's not necessary
    });
  });

NOTE: you can also define an observable like

  permissions$=this.filterInput$
  .pipe(
    debounceTime(300),
    distinctUntilChanged(),
    filter((query) => query?.length >= 3),
    switchMap((query)=>
      this.adminUserService.filterPermission(query).pipe(
        map((res:string[])=>{
          if (this.selectedPermission)
          this.selectedPermission=this.selectedPermission
                              .filter(x=>res.includes(x.label))
          return res.map(x=>({label:x,value:x}))
      })))

  )

And use

<p-multiSelect
      class="add-more-permission-modal__container__filter"
      [options]="(permissions$|async) || undefined"
      ...
</p-multiSelect>

See stackblitz