primefaces / primereact

The Most Complete React UI Component Library
https://primereact.org
MIT License
6.97k stars 1.06k forks source link

Dropdown: Init-Value not working if options have label,value properties #6589

Open sja-cslab opened 6 months ago

sja-cslab commented 6 months ago

Describe the bug

If Dropdown is filled with {label: string, value: any}[] the inital value isn't selected.

Reproducer

https://stackblitz.com/edit/vitejs-vite-2prkbq?file=src%2FApp.tsx

PrimeReact version

10.6.5

React version

18.x

Language

ALL

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

No response

Expected behavior

No response

sja-cslab commented 6 months ago

I noticed that this is not an error. My problem here is noted in the docs:

If optionValue is omitted and the object has no value property, the object itself becomes the value of an option

So this is more a question than a Bug => How can I get and set the Object, even if it has a value property?

Rekl0w commented 6 months ago

https://stackblitz.com/edit/vitejs-vite-tmd4yk?file=src%2FApp.tsx

I changed your code a bit. This should work.

sja-cslab commented 6 months ago

That works, and I'm using it in other parts of my code. However, now if I need to work with that object, for example, in the onChange event, I need to find it within the options. So, that is an acceptable workaround but not a real solution for that problem.

I guess you want to say, 'you cannot get an object directly from the component if it has a value property,' correct?

Rekl0w commented 6 months ago

value prop is need to work with a state that can be changed but if you give a static value to it, it won't change.

I guess you want to say, 'you cannot get an object directly from the component if it has a value property,' correct?

You can get an object with onChange method but this component is not sets the object directly. It sets the value prop and works with it.

sja-cslab commented 6 months ago

@Rekl0w, I see your point; however, it feels wrong that the component works differently based on how something looks inside.

If I pass, for example, [{foo: "label", bar: "value"}, {foo: "label2", bar: "value2"}] and use optionLabel="foo", I'll get the whole object in onChange. If I rename those bar properties to value, it won't work anymore. I hope you get my point.

@melloware Could we make that to a feature/enhancement request? What about an extra option "workWithObject" or something? :)

melloware commented 6 months ago

Yes this has always been a weird contention with using Object vs Primitive and letting it know which JSON fields you mean to use for value and label.

sja-cslab commented 6 months ago

I would expect that if I do not set optionValue, that I get back whatever I throw in.

sja-cslab commented 6 months ago

@melloware just looked at the code

const getOptionValue = (option) => {
    return props.optionValue ? ObjectUtils.resolveFieldData(option, props.optionValue) : ObjectUtils.resolveFieldData(option, 'value') || option;
};

The question I have here is why it has been decided that it is a good idea to try to resolve option.value if no optionValue is set. Why not just return option then? Without digging deeper, I would expect option to be a primitive if only primitives are available.