I have a Map of <String, CartItem> which is a custom class, and I am trying to return specific values from that Map, but every time I do return them in the format item[I], I get a "Null check operator used on a null value." Is there a different way I should be calling this?
Details
I have a map of _items with a public getter that returns those items:
class Cart with ChangeNotifier {
Map<String, CartItem> _items = {};
Map<String, CartItem> get items {
return {..._items};
}
Followed by a function that adds new items to the Map:
void addItem(
String productId,
double price,
String title,
) {
if (_items.containsKey(productId)) {
_items.update(
productId,
(existingCartItem) => CartItem(
id: existingCartItem.id,
title: existingCartItem.title,
price: existingCartItem.price,
quantity: (existingCartItem.quantity 1),
),
);
} else {
_items.putIfAbsent(
productId,
() => CartItem(
id: DateTime.now().toString(),
title: title,
price: price,
quantity: 1,
),
);
}
print(items.length);
print(items[0]);
print(items);
notifyListeners();
}
When I call addItem, this is the output I get from those three print statements - it appears calling as items[0] returns null, even though the length and the full items list print properly:
Performing hot restart...
Restarted application in 1,483ms.
flutter: 1
flutter: null
flutter: {p1: Instance of 'CartItem'}
Then whenever I call that Cart Provider looking for a specific item in the Map:
child: ListView.builder(
itemCount: cart.itemCount,
itemBuilder: (ctx, i) => CartItem(cart.items[i]!)),
)
I get a "Null check operator used on a null value" error. Why is this way of calling the items in the map returning null?
CodePudding user response:
You seem to assume that items[0] works like an array and returns the first element. It does not. A Map has an indexer by key. It returns the item, with the given key. That is the whole point of a map, being able to look up items by key. You set your productId as a key, so to find it you would need to use items[productId].
Some thoughts: does your cart items needs to be a map? If all you want is enumerating through it, it would work if you made it a simple list instead. Then the numeric indexer would work again.
If it needs to be a map, you can use items.values to iterate through all the values. But please note that a map is not ordered. Again, if you need an ordered list, it would be better to use a list in the first place.
