I'm using ng-select
component (https://github.com/valor-software/ng2-select).
I implemented a way to remotely fetch data when the user types.
However, the new data will be fetched and the (items) object populated correctly, but the view is not getting refreshed.
Let me provide you some code:
Here's the template:
<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>
Controller: This method is executed on keypress:
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);
}
Controller: On ngInit I subscribe on that event in order to fetch the new data:
// 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();
}
});
Controller: This is the method to fetch the results:
// 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
});
Everything works correctly with the object: items array is populated and filled correctly. However, The dropdown closes and opens only when I focus out and back in. Seems to be a bug in the component. I also raised an issue on their github:
https://github.com/valor-software/ng2-select/issues/929
Any help is greatly appreciated :)
Now I found a solution.
In the callback, where you need to assign the new items, open the dropdown manually:
// 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;
// [BUGFIX] Here we open the select manually
(<any>this.select).open();
this.loadingResults = false;
},
(error) => {
this.loadingResults = false;
// TODO: Implement proper error handling
});
And remove the [items]
assignment in the component template:
<ng-select
#select
[allowClear]="'true'"
id="DropdownTypeaheadQuestion-{{ question.id }}"
[formControl]="formControlToUse"
placeholder="{{ placeholderText }}"
[multiple]="isMultiple"
(selected)="execSelected($event)"
(typed)="execKeypress($event)">
</ng-select>
So the items will purely be handled over the @ViewChild
assignment in the controller.
Here's the entire solution: Link