28

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.

1
  • You're calling myItemsList.contains(String), but myItemsList doesn't contain Strings; it contains MyItems. Commented Apr 19, 2019 at 7:08

4 Answers 4

44

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);
Sign up to request clarification or add additional context in comments.

Comments

31

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!');
  }
}

4 Comments

Recently getting "Bad State: too many elements error" in Flutter after upgrading. Is there any changes to do or is there any alternative way to do this check?
@Dharaneshvar I wonder what is the code throwing that.
EXACTLY! Thats why I would NOT recommend .singleWhere() .. but instead firstWhere(). Because if more than 1 element is found it will throw StateError. But firstWhere() will just return you that element or execute the orElse: block of code!
@YoApps I updated the answer to reflect when to use singleWhere vs firstWhere
12

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.

Comments

4

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

if (myList.firstWhereOrNull((val) => val.id == someItem.id) != null) {}

1 Comment

Make sure to add this import statement when using firstWhereOrNull: import 'package:collection/collection.dart';

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.