Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

flutter

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.

like image 321
Kavin-K Avatar asked Apr 19 '19 06:04

Kavin-K


4 Answers

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!');
  }
}
like image 164
Radek Avatar answered Oct 29 '22 08:10

Radek


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);
like image 45
Thilo Avatar answered Oct 29 '22 10:10

Thilo


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.

like image 41
ishaan Avatar answered Oct 29 '22 09:10

ishaan


One more way to check does list contain object with property or not

if (myList.firstWhereOrNull((val) => val.id == someItem.id) != null) {}
like image 43
awaik Avatar answered Oct 29 '22 10:10

awaik