Component: p-autocomplete wrong display of chip if multiple=true and optionValue and optionLabel is set
Describe the bug
We've got an p-autocomplete component where we have set multiple = true. And we have set the new option optionValue as well as optionLabel. When selecting an option, the created chip is empty.
Environment
Simple autocomplete component within an reactive angular form with other autocomplete fields which are working correctly when using multiple = false or without an set optionValue.
Reproducer
Angular version
17.3.7
PrimeNG version
17.16.0
Build / Runtime
Angular CLI App
Language
TypeScript
Node version (for AoT issues node --version)
18.14.2
Browser(s)
Chrome
Steps to reproduce the behavior
No response
Expected behavior
Displaying the value of the objects' property defined in optionLabel within the chip .
How can i see the code you wrote in this link?
Sorry, I copied the applicaton url. Here you can see the code: https://stackblitz.com/edit/github-7hs33e-zqqhbr?file=README.md
Encountered a similar issue after upgrading from version 17.13.0 to 17.17.0. Also felt like the newly introduced optionValue input property seemed to be at the root cause.
Potential workaround
Let me start with how I was able to eliminate the problem, as that might already help those encountering the same issue.
We also use it with [multiple]="true" and value binding through formControlName, though did not test their relevance to the issue.
We did not have a value assigned for optionValue in with version 17.13.0, and all worked as expected. Updating to 17.17.0 made the labels of selected options no longer being rendered.
Added:
[optionValue]="optionValueFn"
to the p-autoComplete, with optionValueFn being initialised as:
optionValueFn = (option) => option as any
That solved it for us. Curious whether that can also somehow help you out of a jam, @lorenyaSICKAG.
Short explanation
optionValue expects a value of type string | ((item: any) => string), though that probably is a mistake and should become less strictly typed than the current string expectation. As when assigning (option) => option as any makes the autocomplete behave as before, it feels like under the hood the string type does not actually seem to be a hard expectation.
Towards potential cause
What most probably ís relevant, as already mentioned, is that it feels like the introduction of optionValue introduced an assumption of string typed values on option selection while it did not had such type expectations before.
When not passing any value to the newly introduced optionValue (as it did not exist yet), having updated PrimeNG, regression occurred in our implementation similar to what @lorenyaSICKAG describes.
[!NOTE] The component seems to fallback to
optionLabelto update the value binding when an option gets selected, while before it added the option as-is to the (form control) value.
Illustration of the unexpected behaviour
On selection of an option, with v17.13.0, the form control value used to get updated from
[{ id: 1, label: 'My initialised option' }, { id: 2, label: 'Another initialised option' }]
to
[
{ id: 1, label: 'My initialised option' }, { id: 2, label: 'Another initialised option' },
{ id: 3, label: 'My newly selected option' }
]
With v17.17.0 the same code initialises the value as before:
[{ id: 1, label: 'My initialised option' }, { id: 2, label: 'Another initialised option' }]
But on selection of an additional option, the form control value now becomes:
[
{ id: 1, label: 'My initialised option' }, { id: 2, label: 'Another initialised option' },
'My newly selected option'
]
So this illustrates that at first sight is seems to update the value based on optionLabel (?), which was not the case in v17.13.0.
When removing an option it gets worse, the latter assumption seems to get applied to all initialised values as well, e.g. when removing the second option, the value becomes:
['Another initialised option', 'My newly selected option']`
Reference in
I'm getting issue with the ngmodel not returning model, instead it return string. adding the optionValue="optionValueFn" with optionValueFn = (option) => option as any works for me ..
still, this need to be fixed
Problem still exists, it just behaves a little bit different now. As soon as the suggestion lists does not have the objects which were selected anymore, they become an empty chip. It seems as you need to store the selected suggestions and always add them to the suggestions again.
In my opinion it is wrong to rely on the suggestions, but store the complete selected object somewhere in the component.
Still workaround is to use the selectedItem-template to override the displayed text within the chip. But when deleting an option, the option value of other remaining selected options is getting undefined...
So still cannot use optionLabel and optionValue for [multiple]="true"
PrimeNG Version: 17.18.7 Stackblitz: https://stackblitz.com/edit/github-7hs33e-stqprk
The problem still persists. I found a temporary solution;
@ViewChild(AutoComplete) autoCompleteRef!: AutoComplete;
this.autoCompleteRef.completeMethod.emit({ originalEvent: null as any, query: '' });