-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an ability to override comparator function #296
Comments
You can override the |
@vasilich6107 |
What if I have no access to object class? Imagine that I'm getting user info with role object I have to map this classes into custom objects to have an ability to override |
even if I have an ability to override You have a list of items, that could be disabled on BE. at this point you have a need to inject this preselected item into the list of items with updated name 'deactivated` this is the case when it is nice to have comparator update. Do you see any disadvantages on adding an ability to set custom comparator? |
If it works for you I can create a PR |
You can set custom comparator by using I'm not sure what value will this add over doing: class _MyHomePageState extends State<MyHomePage> {
final List<Item> items = const [
Item('1', 'Item1'),
Item('2', 'Item2'),
Item('3', 'Item3'),
Item('4', 'Item4'),
];
final valueListenable = ValueNotifier<String?>(null);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2<String>(
isExpanded: true,
hint: Text(
'Select Item',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).hintColor,
),
),
items: items
.map((Item item) => DropdownItem<String>(
value: item.id,
height: 40,
child: Text(
item.title,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
valueListenable: valueListenable,
onChanged: (String? value) {
valueListenable.value = value;
},
buttonStyleData: const ButtonStyleData(
padding: EdgeInsets.symmetric(horizontal: 16),
height: 40,
width: 140,
),
),
),
),
);
}
}
class Item {
const Item(this.id, this.title);
final String id;
final String title;
} |
I am experiencing a similar issue. Specifically, I am retrieving a list of users from an API, which includes the currently logged-in user but with less detailed information (same ID, public data, etc.). When I try to set the selected item/object to the logged-in user, the object isn't found because the equality operator (==) is auto-generated by Freezed and I prefer not to modify it. As a workaround, I could replace the logged-in user in the list if it exists or use just IDs as values, though this approach is less intuitive. What is best approach? |
What's wrong with using |
AhmedLSayed9 Thanks. It is true. I was under the impression that the types for items and DropdownButton2 needed to be the same type. ...
items: items //can be type of Item
.map((Item item) => DropdownItem<String>( //type of key
value: item.id,
height: 40, |
The comparison fn compares In your example #296 (comment)
to get the actual item being selected. It would be easier to have comparison function. Could you clarify how suggested approach works with sealed classes which should be compared by type. What should I do if I have
so I want my items to be
The A and B classes does not have similar fields, they could be compared only by type. |
Yes, you'll have to search by id to get the Also, you can always override the
I'm not sure if there's a real use-case like this but anyway, you can do: sealed class A {
const A();
}
class B extends A {
const B();
}
class C extends A {
const C();
} items: const [C(), B(),] |
Yep I have form with the data field. I have a dropdown where I want to put an array of classes as items. Then use dropdown to swap the data class for a part of the form. The dropdown throws cause it is unable to find the value among items... Could you be so kind and allow users to override comparison method? |
Yes, this is not a performance penalty but instead of having a comparison method users have to do the workarounds with id to class mapping. |
The thing is this how the core DropdownButton works and it's more familiar to users. Also, we don't want to add more apis and complicate things unless it's really needed. I still can't find a strong reason for doing: valueComparator: (value) => value.id, rather than: value: value.id, The only benefit here is the user won't need to search back to get the actual item. I'm thinking we might make it optional and keep
which seems a bit weird. That's why I'm a bit skeptical about this change. |
Also, this will break the dropdown menu items consistency, as they use the same type specified for the DropdownButton.
This change will allow items to have different value types which is not allowed. |
Furthermore, You'll have to set |
What about the example with sealed classes? |
I've answered above. |
But if I set the value to dropdown it will produce an assertion error in console that it is not able to find a corresponding item among items |
@vasilich6107 |
Sure |
There are some cases when we have no ability to override the
==
operator for example in case when we get a list of objects from external source.It would be nice to have an ability to override object comparator function which is used to compare objects
The text was updated successfully, but these errors were encountered: