Open vasicvuk opened 9 months ago
Hello @vasicvuk ,
Please provide reproducible example of your issue. This is one codesanbox sample, created by us. You can extend it.
Regards, Lidiya
Hi @LidiyaGeorgieva Here is the reproduction:
https://codesandbox.io/p/sandbox/ui5-webcomponents-forked-xkt62t?file=%2Findex.html%3A2%2C17
Options are loaded with setTimeout to simulate API Requests, value was set before that because we have value immediately but ignored because there were no select options.
Hello @vasicvuk
the Select's value is a bit unique in terms of how it works. While all properties of components cause invalidation of the components and are part of the component's state, the Select's value only proxies to the Options. The Options store the selection state (via Option#selected). Otherwise, we will end up with state in the Select and state in the Options and that will complicate the logic as constant synchronisation between these two states will be required.
So, what you observe is kind of expected - there are no options available, the Select's value can't set the selected property to an Option. In other words, Select's value works only synchronously. Select's value is useful in more straightforward use-cases. Although technically we can address this, we don't really want to, because we would like to keep the selection state only at one place.
In your use-case, with the Options coming later-on, I suggest you opt for setting the selection trough the Option#selected property.
I hope it's won't be that inconvenient.
Best Regards, ilhan
Hi @ilhan007
This is very inconvenient because in most cases the selected value comes from another data source, than the available options. Available options are usually some dictionaries and the values from the real objects. In this way, we cannot do parallel API calls just because of how Select works.
In frameworks such as Angular, we use [(ngModel)] or "formControl" binding, and since this works over the Value property, it would just remove the value from the bound model.
Hello @vasicvuk isn't possible to perform the selection, after you get the options, I assume you have a hook once the API call completes and the options arrive
In addition, in frameworks such as Angular, to be able to use [(ngModel)] or "formControl" binding we have another project https://github.com/SAP/ui5-webcomponents-ngx. It's a wrapper library around our web components for better integration with Angular. Are using the pure UI5 Web Components directly in Angular? And do you use them in Reactive forms as you mentioned?
Hello @vasicvuk isn't possible to perform the selection after you get the options, I assume you have a hook once the API call completes and the options arrive
This is not possible, as the rendering of option items is not done in the same period as you set the items to list, so if I set the items to list and then value, still ui5-option will not be rendered because *ngFor is not yet executed and DOM is not updated yet.
In addition, in frameworks such as Angular, to be able to use [(ngModel)] or "formControl" binding we have another project https://github.com/SAP/ui5-webcomponents-ngx. It's a wrapper library around our web components for better integration with Angular. Are using the pure UI5 Web Components directly in Angular? Do you use them in Reactive forms as you mentioned?
As I see in Angular you are just writing the value directly on Host which will cause the same problem:
I am currently not using this library, because i have my own component wrappers for this and then Angular bindings on top of that.
In addition, in frameworks such as Angular, to be able to use [(ngModel)] or "formControl" binding we have another project https://github.com/SAP/ui5-webcomponents-ngx. It's a wrapper library around our web components for better integration with Angular. Are using the pure UI5 Web Components directly in Angular? Do you use them in Reactive forms as you mentioned?
As I see in Angular you are just writing the value directly on Host which will cause the same problem:
I am currently not using this library, because i have my own component wrappers for this and then Angular bindings on top of that.
I mentioned the ngx wrapper project for your reference - just in case. As long as you have your own wrappers, handling the Angular specifics things - it's ok.
Hello @vasicvuk isn't possible to perform the selection after you get the options, I assume you have a hook once the API call completes and the options arrive
This is not possible, as the rendering of option items is not done in the same period as you set the items to list, so if I set the items to list and then value, still ui5-option will not be rendered because *ngFor is not yet executed and DOM is not updated yet.
Can't you set the selection on the options themselves via the selected property, then it should be fine.
Hello @vasicvuk isn't possible to perform the selection after you get the options, I assume you have a hook once the API call completes and the options arrive
This is not possible, as the rendering of option items is not done in the same period as you set the items to list, so if I set the items to list and then value, still ui5-option will not be rendered because *ngFor is not yet executed and DOM is not updated yet.
Can't you set the selection on the options themselves via the selected property, then it should be fine.
I can mix the information from two data sources, but as I said this is inconvenient, as I would have to wait for a data source for options to load to show all information. This slows done the rendering for no reason. Additionally, I cannot set any info into my model until all the options are loaded.
Probably not optimal, sorry for the inconvenience. However, I am not sure that anything is slowed down, as you are nevertheless waiting for the options, it's just that you have to set the selection along with them using the Option#selected property. Case 1: If the data source for the options come second - use the result from the first data source (that defines the selected value) to set the respective Option's selected property Case 2: If the data source for the options comes first, you nevertheless should wait for the first data source (that defines the selected value) and then Select's value would work
You described Case 1 as problematic, and the suggestion, while not optimal and the most convenient, is to use the result from the first data source (that defines the selected value) to set the respective Option's selected property. Would that be acceptable?
It is not acceptable because I am rendering my options with for loop in framework and model on data source does not have the selected as attribute, which means I have to also have a seperate model and mapping for each select I am having in the app.
It is possible to do, and I am doing so right now but as I said it is very inconvenient.
Bug Description
The method for setting value works by selecting the option from this list like this:
https://github.com/SAP/ui5-webcomponents/blob/main/packages/main/src/Select.ts#L498
In case we are loading the options async, and setting a value before that, the first option is selected rather than the real value.
I tried to find some event when the options are changed so i can change the value then, but didn't find such event.
Affected Component
Select
Expected Behaviour
The value should be considered even if the option does not exists.
Isolated Example
No response
Steps to Reproduce
No response
Log Output, Stack Trace or Screenshots
No response
Priority
None
UI5 Web Components Version
v1.21.2
Browser
Edge
Operating System
Windows
Additional Context
No response
Organization
No response
Declaration