I am a beginner at Flutter and I've been working on an e-commerce app. I used the Provider package to add a product to the cart but I get the following error: My flutter doctor is also just fine. I am having this problem only when I try to add an item to the cart. Any help would be appreciated.
══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown while handling a gesture:
The method 'containsKey' was called on null.
Receiver: null
Tried calling: containsKey("p1")
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 Cart.addItem
package:shop_stop/…/components/cart.dart:33
#2 _ProductItemState.build.<anonymous closure>
package:shop_stop/widgets/product_item.dart:80
My cart provider:
class CartItem {
final String id;
final String title;
final int quantity;
final double price;
CartItem({
@required this.id,
@required this.title,
@required this.quantity,
@required this.price,
});
}
class Cart with ChangeNotifier {
Map<String, CartItem> _items;
Map<String, CartItem> get items {
return {..._items};
}
int get itemCount {
return _items.length;
}
void addItem(
String productId,
double price,
String title,
) {
if (_items.containsKey(productId)) {
// change quantity...
_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,
),
);
}
notifyListeners();
}
}
My product Item:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shop_stop/screens/cart/components/cart.dart';
import '../views/product_details.dart';
import '../models/product.dart';
class ProductItem extends StatefulWidget {
@override
_ProductItemState createState() => _ProductItemState();
}
class _ProductItemState extends State<ProductItem> {
@override
Widget build(BuildContext context) {
final products = Provider.of<Product>(context, listen: false);
final cart = Provider.of<Cart>(context, listen: false);
return Container(
child: GestureDetector(
onTap: () {
Navigator.of(context)
.pushNamed(ProductDetails.routeName, arguments: products.id);
},
child: Card(
color: Colors.white,
elevation: 6,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//product image
Image(image: AssetImage('assets/laptop.jpg')),
Padding(
padding: EdgeInsets.symmetric(vertical: 0, horizontal: 10),
//item name and fav button
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: Text(
products.name,
style: Theme.of(context)
.textTheme
.headline1
.copyWith(fontSize: 16, color: Colors.black),
)),
//add-to-fav button
Consumer<Product>(
builder: (ctx, product, child) => IconButton(
icon: Icon(
products.isFav
? Icons.favorite
: Icons.favorite_border,
color: Colors.red,
),
onPressed: () {
products.toggleFav();
}),
)
],
),
),
// price and buy button
Padding(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: Flex(
direction: Axis.horizontal,
children: <Widget>[
Expanded(
child: Text(
"\$ " + products.price.toString(),
style: Theme.of(context).textTheme.headline1.copyWith(
color: Theme.of(context).primaryColor, fontSize: 15),
)),
SizedBox(
width: 60,
child: RaisedButton(
onPressed: () {
cart.addItem(
products.id, products.price, products.name);
},
color: Colors.orange,
child: Text(
"Buy",
style: TextStyle(fontFamily: 'Prompt', fontSize: 14),
),
),
)
],
),
),
],
),
),
),
);
}
}
Change Map<String, CartItem> _items;
to Map<String, CartItem> _items = {};