ng2-select
ng2-select copied to clipboard
Remote call: Items array doesn't update the view
I have an issue with ng2-select and remote calls: When I type something, my service fetches new items according to the search string. The [items] array is getting updated properly, however the ui is not showing the updated list. Instead, it disappears. Then, when I focusout, the dropdown shows the correct options.
Please see my template here:
<ng-select
#select
[allowClear]="'true'"
id="DropdownTypeaheadQuestion-{{ question.id }}"
[(items)]="items"
[formControl]="formControlToUse"
placeholder="{{ placeholderText }}"
[multiple]="isMultiple"
(selected)="execSelected($event)"
(typed)="execKeypress($event)">
</ng-select>
<i class="fa fa-spinner fa-pulse fa-3x fa-fw font-size-160 loading-icon" *ngIf="loadingResults"></i>
Here's the controller (relevant methods only):
execKeypress($event) {
// When remote, clear all items directly on keypress. Else we have an ugly lag because of the debounce time.
if (this.config.remote === true) {
this.items = [];
}
this.searchSubject.next($event);
}
// Inside ngOnInit I subscribe to the observable
this.searchSubject.debounceTime(500)
.takeUntil(this.ngUnsubscribe)
.subscribe( (searchTextValue: string) => {
// save search string on scope
this.searchTextValue = searchTextValue;
this.config.httpParams = this.config.httpParams.set('search', searchTextValue);
// only send search if more than x chars (or empty)
if (searchTextValue === '' || searchTextValue.length >= this.config.minChars) {
this.fetchResults();
}
});
// fetchResult method fetches the new items and appends them to the items array
this.httpClient.get(url, {params: this.config.httpParams})
.takeUntil(this.ngUnsubscribe)
.subscribe( (res: any) => {
this.items = this.transformSelectableValuesToConsumables(res);
this.select.items = this.items;
this.loadingResults = false;
},
(error) => {
this.loadingResults = false;
// TODO: Implement proper error handling
});
I see that the items array is properly filled, but it's not getting refreshed in the UI. Any help is greatly appreciated! :)
As far as I know, items property cannot be two-way binding but maybe i'm mistaken.
I would replace the [(items)] into [items].
Also i suggest you return the http call as observable to your component and subscribe it from there.
Hi. It was fixed in that fork: https://github.com/optimistex/ng2-select-ex The fork supported with lazy loading of items. Look at this: https://github.com/optimistex/ng2-select-ex/blob/ce8b464dcfdf7e0a1d01b7bb0d2e8660576e31a9/src/ngx-select/ngx-select.component.spec.ts#L808-L839
If you will need more examples text me. I have similar functionality in my different project.
Hi @dave0688,
I've encountered same problem with my app and didn't wanted to change plugin. So after some research and readings I solved it like this;
// service
`/**
- customerSearch - search customers by name and type
- @param customerType string customer type (CANDIDATE, DOMESTIC_CUSTOMER, FOREIGN_CUSTOMER, OTHER, PLUG_CUSTOMER, OTHER, SUPPLIER)
- @param customerName string customer name
- @param matchMode string, default = "STARTS_WITH" */
customerSearch(customerType: string, customerName: string, matchMode: string = 'STARTS_WITH'): Observable
const httpOptions = {
observe: 'response' as 'response',
withCredentials: true,
params: httpParams
};
console.log(httpParams);
return this.http.get<any>(`${this.API_URL}/customer-search`, httpOptions);
}`
// component.ts
`searchCustomer(event, customerType, supplierType: null | string = '') { const customerName = event.term; this.customerService.customerSearch(customerType, customerName).subscribe((data) => { // this.insuranceCustomerData = data.body;
if (customerType === 'SUPPLIER' && supplierType !== null) {
if (supplierType === 'transport') {
this.transportCustomerData = data.body;
} else if (supplierType === 'insurance') {
this.insuranceCustomerData = data.body;
}
}
});
}`
// template.html
<div class="form-group row"> <label class="col-sm-4 col-form-label">Sigorta Firması</label> <div class="col-sm-8"> <ng-select placeholder="Müşteri arama..." [items]="insuranceCustomerData" bindLabel="firmName" bindValue="id" (search)="searchCustomer($event, 'SUPPLIER', 'insurance')"> </ng-select> </div> </div>
and see the result (before search, no inital data)

after key press search;

hope it works for you too ! :)