I am using ngb-typeahed in my angular11 project, I have directive which has typeahed control which is being rendered repeatedly using ng-for,
I have requirement of showing all the available options in typeahed as soon as user click / focus on the control and then gradually filter the list based on users input,
I am able to do this using following code
<div class="mt-3 mb-2">
<div class="row d-flex flex-column justify-content-center">
<div class="col">
<div class="mt-1 mb-4" style="padding-left: 37px" *ngFor="let pl of model.previousplDetails; let i = index">
<div class="row my-3">
<div class="col col-md-10">
<div class="row">
<div class="col col-md-1">
<div class="d-flex justify-content-center">
<img class="coverage-image" [src]="pl.coverage.imageId" alt="">
</div>
</div>
<div class="col d-flex align-items-center">
<h6>{{ pl.coverage.name }}</h6>
</div>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col col-md-6 p-2">
<label for="currentCarrier1" [ngClass]="!pl.isValid?'required':''">Current Carrier</label>
<div>
<input type="text" placeholder="Type here" class="form-control" [(ngModel)]="pl.carrier"
#currentCarrier="ngModel" name="currentCarrier{{i}}" id="currentCarrier{{i}}"
[ngbTypeahead]="search" [inputFormatter]="formatter"
[resultFormatter]="formatter" [editable]='false' (selectItem)="onCarrierSelectItem($event);"
[appRequiredIf]="!pl.isValid"
[placement]="i > model.previousplDetails.length - 3 ? 'top-left' : 'bottom-left'"
[disabled]="isInReadonlyMode" (ngModelChange)="onModelChange(i, 'currentCarrier')"
(focus)="focus$.next($any($event).target.value)"
(click)="click$.next($any($event).target.value)"
autocomplete="nope">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
formatter = (modal: CarrierModel) => modal.name;
@ViewChild('instance', {static: true}) instance: NgbTypeahead;
focus$ = new Subject<string>();
click$ = new Subject<string>();
search: (text$: Observable<string>) => Observable<CarrierModel[]> = (text$: Observable<string>) => {
const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged());
const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.instance.isPopupOpen()));
const inputFocus$ = this.focus$;
return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
map(term => (term === '' ? this.carrierList
: this.carrierList.filter(carrier => new RegExp(term, 'i').test(carrier.name) ||
new RegExp(term ? 'No Current Coverage':'', 'i').test(carrier.name) ||
new RegExp(term ? 'Do not know':'', 'i').test(carrier.name)))));
}
with this code I am able to do achieve what I want to do, but there is one issue with this implementation, that is I have used ng-for here and hence I have multiple typeaheads linked with same subjects (focus$, click$) this causes showing options for all typeaheads when I click one of it.
Is there any way to tackle this situation?
Any help on this is highly appreciated
Thanks in advance.