Introduce special notation for null props
Is your feature request related to a problem? Please describe.
It will be great to have the possibility to permanently or temporarily disable Equatable functionality and compare objects only by references.
Example from bloc library area. In some conditions, we want that new bloc state update the current bloc state of some bloc even if they hold the same data.
Describe the solution you'd like
I propose to introduce special notation for the null value returned by the props method. So if props returned null then objects compared only by references.
Currently, to implement it only one line must be moved (and some tests updated):
index a5e0d52..641588f 100644
--- a/lib/src/equatable_utils.dart
+++ b/lib/src/equatable_utils.dart
@@ -8,8 +8,8 @@ const DeepCollectionEquality _equality = DeepCollectionEquality();
/// Determines whether [list1] and [list2] are equal.
bool equals(List list1, List list2) {
- if (identical(list1, list2)) return true;
if (list1 == null || list2 == null) return false;
+ if (identical(list1, list2)) return true;
final length = list1.length;
if (length != list2.length) return false;
Describe alternatives you've considered
For sure, this functionality could be achieved by override == and hashCode methods in a particular class or some base class. But it all adds redundant code.
Additional context
For now, null and [] values returned by the props method lead to one result - different objects of the same class are equal. With my proposal, they will have a different meaning, which will give additional flexibility.
Hi @ycherniavskyi 👋 Thanks for opening an issue!
Can you please provide a use-case for the proposed changes? Thanks!
@felangel my case when I need such possibility (currently I implement it by override operator == and hashCode with Object identical and identityHashCode appropriately) is to complete Future returned by onRefresh method of RefreshIndicator.
I implemented it a bit differently (add the snippet below) than in your Flutter Weather Tutorial but got the same issue as I understand your tutorial also has. That is why I provide my description base on this tutorial.
If for some reason after activating RefreshIndicator during processing RefreshWeather event in _mapRefreshWeatherToState weatherRepository.getWeather return exactly the same data/object as for example for the previous refresh, then new WeatherLoaded state object will be equal, from Equatable point of view to the previous state and as result, listener handler of BlocConsumer will not call (because of this condition) and _refreshCompleter will not complete. Fuf 😊.
That is why it will be great to have the possibility to disable (temporary with some condition or permanently) Equatable functionality without overriding of operator == and hashCode method but only by returning null as result of props getter.
Which seems rather logical for me - if you return null then it seems that you don't want to apply the functionality of this getter (which is the core of Equatable functionality), and if you return [] then it seems that you want to apply the functionality with the understanding that all instances of such class will be equals.
And finnaly my implementation of RefreshIndicator usage:
return RefreshIndicator(
onRefresh: () {
hideSnackBar(context);
return (BlocProvider.of<ContactsBloc>(context)..add(ContactsRefreshed()))
.skip(1)
.firstWhere((state) => state is ContactsLoadSuccess || state is ContactsRefreshFailure);
},
child: Container(),
);
@ycherniavskyi thanks for the clarification. @jorgecoca what are your thoughts on this?
@ycherniavskyi Thank you for opening this issue! This feedback is really appreciated! ;)
I personally do not see a good fit for this in Equatable. My concern is that, by introducing a change like this, it makes the library less predictable: in my mind, equatable somehow gets you closer to a "data class" from Kotlin (that is, just a pure model that provides a well-known equality model/algorithm, and a string representation). Whatever gets you away from that predictable behavior should be considered custom, and for that, I'd suggest relaying on operator == and hashCode.
Pity, but ok.
In such a case I suggest you to extend the documentation with a more detailed description of "special" props return values, such as null and [].