nebular: NbSelect doesn't display the [selected] option if data is dynamic
Issue type
I’m submitting a … (check one with “x”)
- bug report
- feature request
Issue description
Current behavior: I have a NbSelect populated with options from the database. Neither using [selected] or ([ngModel]) makes it display the selected value. As soon as I pass static data it works as intended.
Expected behavior: It should automatically select the selected option.
Steps to reproduce: Put NbSelect on page, have a simple MySQL database to support the exchange of data, take the data and put them as options.
Related code: Unfortunately since it requires my localhost mySQL here, I can’t provide a stackblitz, but I can include some snippets.
header.component.html
<nb-select (selectedChange)="changeLang($event)" ([ngModel])="selectedLang">
<nb-option *ngFor="let lang of languages" [value]="lang">{{ lang.short }}</nb-option>
</nb-select>
header.component.ts
service.exp.subscribe((exp: any) => {
this.languages = exp.langs.map(x => {
return {
short: x.short,
name: x.name
}
});
this.selectedLang.next(this.languages.filter(x => x.short === translate.currentLang)[0]);
});
header.service.ts
this.server.getLangsList().subscribe((langs: any) => {
this.exp.next({
langs: langs
});
});
server.service.ts
getLangsList() {
return this.request('GET', `http://localhost:8080/langs`);
//return of([{"idLang":1,"short":"en","name":"English","dateFormat":"YYYY-MM-DD","dateTimeFormat":"YYYY-MM-DD HH:mm:ss"}]);
}
Now, in the last snippet, the two rows return the same Observable. In the caso of the second (static data) it displays the [selected] value correctly, in the first it doesn’t.
I’m not sure it’s related to the issue 2088, so I started a new issue #2088
Other information:
npm, node, OS, Browser
Node version 10.16.0
npm version 6.10.3
Windows 10, on Chrome
Angular, Nebular
ngx-admin v4.0.1, nebular v4.1.2
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 19
- Comments: 21 (1 by maintainers)
I have used @shireefadel’s workaround as follows:
#select
on the nb-select element.This is extremely dirty, but it will work until this bug is fixed.
thanks, it helped me a lot to create a generic function
I hope it works for someone else. Thanks again @ironsm4sh
The issue is still present in nebular 8. Any news? I created a repo nb-select-issue with the issue and the solution proposed by @ironsm4sh and @rardila-uniajc and works fine. Thanks
until it´s fixed: setting “selected” in
ngAfterViewInit
works for me…This will work
in the html, add a #select on the nb-select element.
in the ts, add a ViewChild to you variables.
add this function
and call the function giving it the default value when you subscribe
@michabbb that works when initially setting the select right after component loads, however after a while I also have to change its value from outside (from another server request) and at that time the component doesn’t show the updated value (even if the correct item is selected when opening the dropdown)
Works for me, many thanks
Thank you jrasm91, I think this is the best explanation of the problem, took me a while to reach the same conclusion. I had the same problem but with template based forms, and was able to “solve” it by making sure that the variable that contains the options list for
<nb-option>
is set before changing<nb-select>
attached ngModel (Of course mine is not a solution, only a weak workaround)I ran into this issue when I was dynamically updating the underlying
nb-option
s, while simultaneously changing theselected
value.Solution I fixed the issue by wrapping the
selected
update in asetTimeout
.Explanation Using
formControlName
orngModel
uses angular’s value accessor, which callswriteValue
on theNbSelectComponent
. I believe the problem is that this happens before the underlying options are re-rendered. Basically, theNbSelectComponent
runs compare/matching logic against the wrong (old)NbOption
list, which is why it doesn’t show as “selected”. Adding asetTimeout
just delays the “selected” change until after the newNbOption
components are updated. Now when it runs, it finds the matchingNbOption
and marks it as selected.The issue seems to be due to the component not re-evaluating the selected value when the options are updated dynamically after the value is assigned somehow. My workaround was to clear the value and then set it again with a deferred call (setTimeout with 0 duration) and calling changeDetectorRef.markForCheck().
Something like this: