ng-bootstrap: Regression: ngModel doesn't work with search function bind(this) ([ngbTypeahead]="search.bind(this)")
Bug description:
In case if I use search.bind(this) ngModel isn’t working, data isn’t set to model
html:
<input
id="typeahead-basic"
type="text"
[ngbTypeahead]="search.bind(this)"
class="form-control"
[(ngModel)]="model"/>
ts:
search(text$: Observable<string>) {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
map(term => term.length < 2 ? []
: this.states.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10))
)
}
This was working on v/7.0.0
Link to minimally-working StackBlitz that reproduces the issue:
https://angular-dd3z93.stackblitz.io
Versions of Angular, ng-bootstrap and Bootstrap:
Angular: 11.2.7
ng-bootstrap: 9.1.0
Bootstrap:
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 5
- Comments: 28
@KyleThenTR To keep things short, my scenario consisted on a table with rows rendered via a ngFor. Each row had a typeahead. I passed a parameter to each typeahead to allow them to know which row they corresponded to. To avoid passing a parameter, I simply encapsulated each row into its own Component. That way, the parameter became one of the Input properties of this new Component, so there was no need to use a parameter in the typeahead function; simple grab that information from the Component itself.
The proposed workaround is to use a pure pipe. It’s really suuuuper easy:
with your
typeaheadFunctionbeing something along the lines ofreally not sure if I’m a fan 🤔
I was able to work around the issue and keep the debounceTime operator by turning the search function into an arrow function and removing the .bind(this) from the template.
Perhaps related, I was using a search function with an additional parameter which is no longer working since v9.1.0, commit 81f2c59.
HTML:
Updating the function typings hasn’t worked either, the search function is triggered but the
text$observable is never updated.Use a pipe then.
Neither. Functions that are returning different
REFERENCEeach time they get called is an anty pattern.There are changes. Angular calls your function to check if there are changes, as you return a new function reference every time it detects changes and calls the
ngOnChangesof the typeahead.Angular components’ datepicker has similar issues. They could solve it by comparing dates, but these are functions.
@KyleThenTR I ended up using other component variables to find what would have been the template parameter. I think my use case was lucky, since the parameter I need is tracked in a component variable that is indexed by the selected typeahead.
I have the same scenario as @athisun in my application, after updating from v7 to v10 it no longer works. I have other typeaheads with no parameters, those work correctly.
I can get away with this by refactoring my Component, but this is clearly an undocumented breaking change. Any updates?
I have the same problem. It is working on 9.0.2