Flutter: freezed custom operator == does not work as I accept - flutter

I am using freezed and I have list of object, I override my freezer class like this:
#override
bool operator ==(Object other) =>
other is _ServiceItemModel &&
id == other.id &&
product.id == other.product.id &&
product.externalId == other.product.externalId &&
internalId == other.internalId &&
identical(other, this);
#override
int get hashCode => [id, product.id, product.externalId, internalId].hashCode;
my question is why the value of bool iseq = identical(servicesItem, oldService ); return false !
servicesItem and oldService are List of ServiceItemModel.

you should remove this line
identical(other, this);

Related

List contains method in dart

Contain method can not detect the object inside of list
What is the reason of that?
I expected to get the result of if block
enter image description hereLook at this picture as well.In the second picture it works
it's because your Contact object has no == relation between its instances,
so trying to compare two instances like this:
Contact(false, "") == Contact(false, "") // false
And the contains method follows the same comparison I did to find if a list contains that object.
It would help if you told Dart when two objects of that class should be considered equal to each other, by overriding the == operator like this:
class Country {
final bool? brotherCountry;
final String? name;
Country(this.brotherCountry, this.name);
#override
bool operator ==(covariant Country other) {
return other.name == name && other.brotherCountry ==brotherCountry;
}
}
now trying this:
Country(false, "") == Country(false, "") // true
and so on now the contains method will work as you expect
[Country(false, ""), Country(false, "test")].contains(Country(false, "")); // true
You can override the == operator on Country like so to get it to work:
class Country {
bool? brotherCountry;
String? name;
Country(this.brotherCountry, this.name);
#override
bool operator ==(Object other) {
if (other is Country) {
return name == other.name && brotherCountry == other.brotherCountry;
}
return false;
}
#override
int get hashCode => brotherCountry.hashCode ^ name.hashCode;
}
Alternatively, there's this package https://pub.dev/packages/equatable, and you can use it like so:
class Country extends Equtable {
bool? brotherCountry;
String? name;
Country(this.brotherCountry, this.name);
#override
List<Object> props => [brotherCountry, name];
}
As pointed about by jamesdlin, it's not because of call by value
From Effective dart, it says:
Any two objects that are equal must have the same hash code. Otherwise, maps and other hash-based collections will fail to recognize that the two objects are equivalent.

Dealing with multiple condition if statement in Dart

Hi I need help simplifying this if statement with multiple conditions but I'm not sure how to as every attempt I've had cluttered my code even more :
if (isAirplane(element) && isFlying(element) && isRed(element)) return redFlyingAirplane;
if (isAirplane(element) && isFlying(element) && !isRed(element)) return greenFlyingAirplane;
if (isAirplane(element) && !isFlying(element) && isRed(element)) return redGroundedAirplane;
if (isAirplane(element) && !isFlying(element) && !isRed(element)) return greenGroundedAirplane;
if (!isAirplane(element) && isFlying(element) && isRed(element)) return redFlyingHelicopter;
if (!isAirplane(element) && isFlying(element) && !isRed(element)) return greenFlyingHelicopter;
if (!isAirplane(element) && !isFlying(element) && isRed(element)) return redGroundedHelicopter;
if (!isAirplane(element) && !isFlying(element) && !isRed(element)) return greenGroundedHelicopter;
EDIT :
Adding some extra context in which I'm using this :
late BitmapDescriptor redFlyingAirplane;
late BitmapDescriptor greenFlyingAirplane;
...
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_initMarkers();
});
}
void _initMarkers() async {
redFlyingAirplane = await LoadBitmaps.redFlyingAirplane;
greenFlyingAirplane = await LoadBitmaps.greenFlyingAirplane;
...
}
BitmapDescriptor resolveBitmap(Something element) {
if (isAirplane(element) && isFlying(element) && isRed(element)) return redFlyingAirplane;
if (isAirplane(element) && isFlying(element) && !isRed(element)) return greenFlyingAirplane;
...
}
You have 3 booleans, so 8 possible outcomes, and these can be represented in 3 bits with values 0 to 7.
First define a function that turns 3 booleans into that integer, such as:
int bitmapIndex(bool isAirplane, bool isRedColor, bool isFlyingNow) =>
(isAirplane ? 4 : 0) + (isRedColor ? 2 : 0) + (isFlyingNow ? 1 : 0);
Then store your bitmaps in a map, indexed by integer, for example:
final bitmaps = <int, BitmapDescriptor>{};
When you come to load the bitmaps store them in the map:
bitmaps[bitmapIndex(true, true, true)] = await LoadBitmaps.redFlyingAirplane;
bitmaps[bitmapIndex(true, true, false)] = await LoadBitmaps.redGroundedAirplane;
Finally, to access any bitmap, simply look it up:
return bitmaps[bitmapIndex(isAirplane(element), isFlying(element), isRed(element))];
I've taken a similar approach as BBK, but extracted variables for the methods that are called > 1 times, not knowing how "costly" those operations are, and added the use of ternary operator to make it more compact:
var isRedColor = isRed(element);
var isFlyingNow = isFlying(element);
if (isAirplane(element)) {
if (isFlyingNow) {
return isRedColor ? redFlyingAirplane : greenFlyingAirplane;
}
return isRedColor ? redGroundedAirplane : greenGroundedAirplane;
}
if (isFlyingNow) {
return isRedColor ? redFlyingHelicopter : greenFlyingHelicopter;
}
return isRedColor ? redGroundedHelicopter : greenGroundedHelicopter;
Nested If Statements may be used in this case. There is no need to use else conditions since you return a value for every case. The rest of the code won't run in any way if the condition is met.
if (isAirplane(element)) {
if (isFlying(element)) {
if (isRed(element)) return redFlyingAirplane;
return greenFlyingAirplane;
}
if (isRed(element)) return redGroundedAirplane;
return greenGroundedAirplane;
}
if (isFlying(element)) {
if (isRed(element)) return redFlyingHelicopter;
return greenFlyingHelicopter;
}
if (isRed(element)) return redGroundedHelicopter;
return greenGroundedHelicopter;

Dart equality for different types

I want to implement class-like enum
#immutable
abstract class Enum<T> {
final T? value;
#literal
const Enum([this.value]);
List<Object?> get values => value != null ? [value] : const [];
#override
bool operator ==(Object? other) {
if (other is T) {
return value == other;
}
return other is Enum && other.value == value;
}
#override
int get hashCode => super.hashCode;
}
class EnumClass extends Enum<int> {
#literal
const EnumClass(int value) : super(value);
static const zero = const EnumClass(0);
static const one = const EnumClass(1);
// You can have any functions you want
}
so that I can do the following operations
if(EnumClass.zero == 0) {
// This works!
}
but my test failed
void main() {
test('Compare EnumClass.zero with 0', () {
if (EnumClass.zero == 0) {
print('same'); // This is printed
}
expect(EnumClass.zero, 0); // But the test failed
});
}
The comparison with 0 works as expected but the expect function doesn't work.
What should I do to make the test pass?
Note that:
expect(EnumClass.zero, 0);
fails, but:
expect(0, EnumClass.zero);
succeeds. expect(actual, expected) by default uses an equals Matcher, and the implementation for equals checks expected == actual instead of actual == expected.
Arguably it'd be more intuitive if expect(A, B) matched the original order by comparing A == B instead of B == A, but having non-symmetric equality is going to be error-prone and probably is not a good idea anyway.
Also see https://github.com/dart-lang/matcher/issues/94.

Check whether a list contain an attribute of an object in dart

I need to check whether myItemsList contains myitem.itemId or not, If it exists need to add itemQuantity, if it not exists need to add myitem object to myItemsList.
List<MyItem> myItemsList = new List();
MyItem myitem = new MyItem (
itemId: id,
itemName: name,
itemQuantity: qty,
);
if (myItemsList.contains(myitem.itemId)) {
print('Already exists!');
} else {
print('Added!');
setState(() {
myItemsList.add(myitem);
});
}
MyItem class
class MyItem {
final String itemId;
final String itemName;
int itemQuantity;
MyItem ({
this.itemId,
this.itemName,
this.itemQuantity,
});
}
above code is not working as expected, please help me to figure out the issue.
Contains() compares the whole objects.
Besides overriding == operator or looping over, you can use list's singleWhere method:
if ((myItemsList.singleWhere((it) => it.itemId == myitem.itemId,
orElse: () => null)) != null) {
Edit:
As Dharaneshvar experienced and YoApps mentioned in the comments .singleWhere raises StateError when more elements are found.
This is desired when you expect unique elements such as in the case of comparing IDs.
Raised error is the friend here as it shows that there is something wrong with the data.
For other cases .firstWhere() is the right tool:
if ((myItemsList.firstWhere((it) => it.itemName == myitem.itemName,
orElse: () => null)) != null) {
// EO Edit
Whole example:
List<MyItem> myItemsList = new List();
​
class MyItem {
final String itemId;
final String itemName;
int itemQuantity;
​
MyItem({
this.itemId,
this.itemName,
this.itemQuantity,
});
}
​
void main() {
MyItem myitem = new MyItem(
itemId: "id00",
itemName: "name",
itemQuantity: 50,
);
​
myItemsList.add(myitem);
​
String idToCheck = "id00";
​
if ((myItemsList.singleWhere((it) => it.itemId == idToCheck,
orElse: () => null)) != null) {
print('Already exists!');
} else {
print('Added!');
}
}
As already said before, contains compares two Objects with the == operator. So you currently compare MyItem with String itemId, which will never be the same.
To check whether myItemsList contains myitem.itemId you can use one of the following:
myItemsList.map((item) => item.itemId).contains(myitem.itemId);
or
myItemsList.any((item) => item.itemId == myitem.itemId);
You're using contains slightly wrong.
From: https://api.dartlang.org/stable/2.2.0/dart-core/Iterable/contains.html
bool contains(Object element) {
for (E e in this) {
if (e == element) return true;
}
return false;
}
You can either override the == operator, see: https://dart-lang.github.io/linter/lints/hash_and_equals.html
#override
bool operator ==(Object other) => other is Better && other.value == value;
Or you can loop over your list and search the normal way one by one, which seems slightly easier.
One more way to check does list contain object with property or not
if (myList.firstWhereOrNull((val) => val.id == someItem.id) != null) {}

isTransparentResolver() in wicket 6.x or 7.x

I have below code need to change it to wicket 6.6, but isTransparentResolver() is removed and I am trying according to this link
https://www.mail-archive.com/commits#wicket.apache.org/msg17546.html
but no use, anybody have solution for below code?
add(new WebMarkupContainer("bodyElement") {
#Override
public boolean isTransparentResolver() {
return true;
}
#Override
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
if ((usrLoginHstryList == null || usrLoginHstryList.isEmpty()) &&
(usrChangeHstryList == null || usrChangeHstryList.isEmpty())) {
tag.put("onload", "hideHistoryButtons();");
} else if (usrLoginHstryList == null || usrLoginHstryList.isEmpty()) {
tag.put("onload", "hideUserLoginHstryBtn();");
} else if (usrChangeHstryList == null || usrChangeHstryList.isEmpty()) {
tag.put("onload", "hideUserChngHstryBtn();");
}
}
});
Finally I have written this using TransparentWebMarkupContainer
add(new TransparentWebMarkupContainer("bodyElement"){
#Override
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
if((usrLoginHstryList == null || usrLoginHstryList.isEmpty()) && (usrChangeHstryList == null || usrChangeHstryList.isEmpty())){
tag.put("onload", "hideHistoryButtons();");
}else if(usrLoginHstryList == null || usrLoginHstryList.isEmpty()){
tag.put("onload", "hideUserLoginHstryBtn();");
}else if(usrChangeHstryList == null ||usrChangeHstryList.isEmpty()){
tag.put("onload", "hideUserChngHstryBtn();");
}
}
});