3

I have my Cart model as below

class Cart {
  String description;
  double unitCost;
  double amount;
  int quantity;
  String color;
  String imageURl;

  Cart({
    this.description,
    this.unitCost,
    this.amount,
    this.color,
    this.quantity,
    this.imageURl,
  });
}

And my CartData notifier class which has a _cartList with pre-loaded data as shown below:

class CartData extends ChangeNotifier {
  List<Cart> _cartItems = [
    Cart(
      imageURl:
          'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg',
      description: 'Nike Air Max',
      quantity: 3,
      unitCost: 6000,
    ),
    Cart(
      color: 'red',
      description: 'Nike Air Max',
      quantity: 3,
      unitCost: 3000,
    ),
    Cart(
      imageURl:
          'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg',
      description: 'Nike Air Max',
      quantity: 6,
      unitCost: 6000,
    ),
    Cart(
      color: 'purple',
      description: 'Nike Air Max',
      quantity: 2,
      unitCost: 1000,
    ),
    Cart(
      color: 'purple',
      description: 'Nike Air Max',
      quantity: 2,
      unitCost: 2000,
    ),
  ];

  UnmodifiableListView<Cart> get cartItems {
    return UnmodifiableListView(_cartItems);
  }

  int get cartItemsCount {
    return _cartItems.length;
  }

  void addItemToCart(
    String color,
    double unitCost,
    String description,
    String imageURL,
    int quantity,
  ) {    
    _cartItems.insert(
      0,
      Cart(
        color: color,
        unitCost: unitCost,
        description: description,
        imageURl: imageURL,
        quantity: quantity,
      ),
    );

    notifyListeners();
  }

  void getTotalSum(Cart cart) {}

  double getAmount(int qty, double unitCost) {
    return qty * unitCost;
  }

  void upDateCartItem(Cart cartItem, bool isIncrementing) {
    if (isIncrementing == true) {
      cartItem.quantity++;
      print(
          'Cart item purchase quantity is: ${cartItem.quantity}, after incrementing from updateCartItem');
    } else {
      if (cartItem.quantity >= 1) {
        cartItem.quantity--;
        print(
            'Cart item purchase quantity is: ${cartItem.quantity} after decrementing from updateCartItem');
      }
      if (cartItem.quantity == 0) {
        deleteItemFromCart(cartItem);
      }
      print(cartItem.quantity);
    }

    cartItem.amount = cartItem.quantity * cartItem.unitCost;
    print('Cart Item amount is: ${cartItem.amount} from updateCartItem');

    notifyListeners();
  }

  void deleteItemFromCart(Cart cartItem) {
    _cartItems.remove(cartItem);
    notifyListeners();
  }
}

I want to be able to add items on the fly to my existing list of Cart Items using my addItemToCart() method, and display them immediately on my shopping cart page.

In my shopping screen, I have a few declarations as below:

  String defaultDescription = 'add description';
  String paymentDescription = 'add description';
  String amount = '0';
  int cartTotal = 0;

However, I'm unable to add item(s) to cart from my shopping screen when I call the addItemToCart method as below:

 _addToCart() {
    if (amount == '' || amount == '0') {
      print('add an amount');
      _showToast(this.context, 'amount');
    } else if (paymentDescription == defaultDescription) {
      print('please enter a valid description to proceed');
      _showToast(this.context, 'payment description');
    } else {
      print(amount);
      print(paymentDescription);
      //do something like add to cart
      CartData cartData = Provider.of<CartData>(context, listen: false);

      cartData.addItemToCart(
        null,
        double.parse(output),
        paymentDescription,
        null,
        1,
      );
    }  
    setState(() {
      paymentDescription = defaultDescription;
      amount = '0';
    });
 }

Here's my checkout screen that displays the cart Items:

class CheckoutScreen extends StatefulWidget {
  static const String id = 'checkout_screen';

  @override
  _CheckoutScreenState createState() => _CheckoutScreenState();
}

class _CheckoutScreenState extends State<CheckoutScreen> {
  @override
  void initState() {
    super.initState();

    CustomerNotifier customerNotifier =
        Provider.of<CustomerNotifier>(context, listen: false);
    customerNotifier.getCustomers(customerNotifier);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ChangeNotifierProvider(
          create: (context) => CartData(),
          child: Consumer<CartData>(
            builder: (context, cartData, child) {
              return Column(
                children: <Widget>[
                  Row(
                    children: <Widget>[
                      IconButton(
                        icon: Icon(
                          Icons.arrow_back_ios,
                          color: Colors.black26,
                        ),
                        onPressed: () => Navigator.pop(context),
                      ),
                      Text(
                        'Shopping cart',
                        style: TextStyle(
                          fontSize: 21.0,
                          color: Colors.black26,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ],
                  ),
                  Container(
                    margin: EdgeInsets.only(top: 8.0, bottom: 8.0),
                    height: MediaQuery.of(context).size.height / 16,
                    width: MediaQuery.of(context).size.width - 150,
                    decoration: BoxDecoration(
                      border: Border.all(color: kThemeStyleButtonFillColour),
                      borderRadius: BorderRadius.circular(5.0),
                    ),
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(
                          'Customer drop down',
                          textAlign: TextAlign.center,
                          style: kRegularTextStyle,
                          maxLines: 2,
                          textDirection: TextDirection.ltr,
                          softWrap: true,
                        ),
                        SizedBox(width: 5.0),
                        Icon(
                          Icons.keyboard_arrow_down,
                          color: kThemeStyleButtonFillColour,
                          size: 25,
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 4,
                    child: Container(
                      height: MediaQuery.of(context).size.height - 225,
                      padding: const EdgeInsets.only(
                          left: 16, right: 16, bottom: 8.0),
                      child: ListView.builder(
                        itemCount: cartData.cartItems.length,
                        shrinkWrap: true,
                        itemBuilder: (context, index) {
                          final cartItem = cartData.cartItems[index];

                          return cartData.cartItems.isEmpty
                              ? Container(
                                  child: Align(
                                      alignment: Alignment.center,
                                      child: Text('Your cart is empty')))
                              : Container(
                                  color: Colors.white,
                                  margin: EdgeInsets.symmetric(vertical: 6.0),
                                  child: Row(
                                    children: <Widget>[
                                      Expanded(
                                        child: Container(
                                          width: 80.0,
                                          height: 70.0,
                                          child: Center(
                                            child: cartItem.imageURl == null
                                                ? Container(
                                                    padding:
                                                        EdgeInsets.all(4.0),
                                                    decoration: BoxDecoration(
                                                      color: Color((math.Random()
                                                                      .nextDouble() *
                                                                  0xFFFFFF)
                                                              .toInt())
                                                          .withOpacity(1.0),
                                                      borderRadius:
                                                          BorderRadius.circular(
                                                              20.0),
                                                    ),
                                                  )
                                                : Container(
                                                    padding:
                                                        EdgeInsets.all(4.0),
                                                    decoration: BoxDecoration(
                                                      image: DecorationImage(
                                                        fit: BoxFit.cover,
                                                        image: NetworkImage(
                                                            cartItem.imageURl),
                                                      ),
                                                      borderRadius:
                                                          BorderRadius.circular(
                                                              20.0),
                                                    ),
                                                  ),
                                          ),
                                        ),
                                      ),
                                      SizedBox(width: 12.0),
                                      Column(
                                        crossAxisAlignment:
                                            CrossAxisAlignment.start,
                                        children: <Widget>[
                                          Container(
                                            width: 100.0,
                                            child: Text(
                                              cartItem.description,
                                              style: TextStyle(
                                                  fontWeight: FontWeight.bold),
                                            ),
                                          ),
                                          SizedBox(height: 8.0),
                                          Row(
                                            children: <Widget>[
                                              GestureDetector(
                                                child: Container(
                                                  width: 20.0,
                                                  height: 20.0,
                                                  decoration: BoxDecoration(
                                                    color: Colors.grey[200],
                                                    borderRadius:
                                                        BorderRadiusDirectional
                                                            .circular(4.0),
                                                  ),
                                                  child: Icon(
                                                    Icons.remove,
                                                    color: Colors.white,
                                                    size: 15.0,
                                                  ),
                                                ),
                                                onTap: () {
                                                  cartData.upDateCartItem(
                                                      cartItem, false);
                                                },
                                              ),
                                              Padding(
                                                padding:
                                                    const EdgeInsets.symmetric(
                                                        horizontal: 15.0),
                                                child: Text(
                                                  '${cartItem.quantity}',
                                                  style: TextStyle(
                                                      fontWeight:
                                                          FontWeight.bold,
                                                      fontSize: 15.0),
                                                ),
                                              ),
                                              GestureDetector(
                                                child: Container(
                                                  width: 20.0,
                                                  height: 20.0,
                                                  decoration: BoxDecoration(
                                                    color:
                                                        kThemeStyleButtonFillColour,
                                                    borderRadius:
                                                        BorderRadiusDirectional
                                                            .circular(4.0),
                                                  ),
                                                  child: Icon(
                                                    Icons.add,
                                                    color: Colors.white,
                                                    size: 15.0,
                                                  ),
                                                ),
                                                onTap: () {
                                                  cartData.upDateCartItem(
                                                      cartItem, true);
                                                },
                                              ),
                                            ],
                                          ),
                                        ],
                                      ),
                                      // Spacer(),
                                      Expanded(
                                        child: Text(
                                          '${cartData.getAmount(cartItem.quantity, cartItem.unitCost)}',
                                          style: TextStyle(
                                              fontWeight: FontWeight.bold,
                                              fontSize: 15.0),
                                        ),
                                      ),
                                      Expanded(
                                        child: GestureDetector(
                                          child: Icon(
                                            Icons.delete_forever,
                                            size: 25.0,
                                            color: kThemeStyleButtonFillColour,
                                          ),
                                          onTap: () => cartData
                                              .deleteItemFromCart(cartItem),
                                        ),
                                      ),
                                    ],
                                  ),
                                );
                        },
                      ),
                    ),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    );
  }
}

What could I be missing here?

hermie_brown
  • 319
  • 9
  • 24

1 Answers1

0

Calling your addItemToCart() should rebuild the children inside Consumer<CartData>() because of notifyListeners(). This should help you give some clue on what's happening.

Add a debugPrint('List length: ${cartData.cartItemsCount}') inside the Consumer to check if List _cartItems changes after adding an item.

Omatt
  • 8,564
  • 2
  • 42
  • 144