shopping_cart

Creator: coderz1093

Last updated:

Add to Cart

Description:

shopping cart

About ShoppingCart
Installing

Additional dependencies


Usage

Creating custom item class
Initialisation
Get instance
Getters

CartItems
CartTotal
TotalCartPriceInt
itemCount
cartItemsStream


Methods

Get item from cart
Finding an item by ID
Has item with id
Contains cart item
Adding items to the cart
Removing items from the cart
Increment item quantity
Decrement item quantity
Calculate item total price by ID
Update item
Refresh cart
Clear all items


Rebuild ui

Use Get
Use StreamBuilder




Conclusion

About ShoppingCart #
ShoppingCart is a Flutter library that simplifies the creation and management of a shopping cart in your Flutter applications.
Installing #
Add the following dependency to your pubspec.yaml file:
dependencies:
shopping_cart: ^0.0.1
copied to clipboard
Then, import the library in your Dart code:
import 'package:food_cart/food_cart.dart';
copied to clipboard
Additional dependencies #
I also recommend adding the following 2 packages, they are necessary for the full functioning of the library.
dependencies:
get:
equatable:
copied to clipboard

"Get" is an excellent state management tool. The ShoppingCart is made using it. You will need it if you want to make the values of the shopping cart observable (like items in cart screen or total cart price for example). But it's not mandatory, as I've added the ability to use Streams if you don't want to use Get.
The package "Equatable" is necessary to compare the models of your products in the cart and find the necessary one.

Usage #
Creating custom item class #
Firstly you need to create a model of your product, this is a mandatory step!
Simply create a class with any name and extend it from the ItemModel class, which is part of this package, and also, if you added the equatable package, add the EquatableMixin mixin.
import 'package:equatable/equatable.dart';
import 'package:food_cart/food_cart.dart';

class FoodModel extends ItemModel with EquatableMixin {
// Create all the fields of the class
// that you need for your specific case.
final String name;
final String urlPhoto;
String specialInstruction;

FoodModel({
required this.name,
required this.urlPhoto,
this.specialInstruction = '',

// this field come from ItemModel class
required super.id,

// This field come from ItemModel class
required super.price,

// This field come from ItemModel class
super.quantity = 1,
});


// This line of code comes from equatable package,
// and it is required! In square brackets pass all fields
// from your model, but don't pass 'id', 'price' and 'quantity'!!!
@override
List<Object?> get props => [ name, urlPhoto, specialInstruction];
}
copied to clipboard
The abstract class ItemModel already has 3 mandatory fields without which nothing will work:

Unique id (id)
Quantity of goods (quantity)
Cost of goods (price)

Therefore, please do not recreate these fields in your class!
Initialisation #
After you have created your item model, it is necessary to initialize the shopping cart. This should be done before you start using the API of this package.
To get started, call the ShoppingCart.init<T>() method to initialize a new instance of Cart
ShoppingCart.init<FoodModel>();
copied to clipboard
Get instance #
One of the great advantages of my package is that you can get the cart instance anywhere in your code and you don't need to save and pass it from screen to screen on your own.
To retrieve the current instance of Cart
final cart = ShoppingCart.getInstance<FoodModel>();
copied to clipboard
Make sure to pass your item model class that you created at the beginning of this guide in <> brackets, in my case it's FoodModel. If you don't pass it, you will get an error!
Getters #
CartItems
To get the list of items in the cart, simply access the cartItems getter.
final instance = ShoppingCart.getInstance<FoodModel>();

final items = instance.cartItems;
copied to clipboard
The cartItems object is already observable and has the type RxList<T> since I used Get package.
CartTotal
Returns the total price of all items in the cart.
final instance = ShoppingCart.getInstance<FoodModel>();

final cartTotal = instance.cartTotal;
copied to clipboard
This getter calculates the total price of all items in the cart by iterating through cartItems and adding the price of each item multiplied by its quantity. The result is returned as a double.
TotalCartPriceInt
This getter returns the total price of all items in the cart as an integer. This is simmilar to cartTotal, but it return int
final instance = ShoppingCart.getInstance<FoodModel>();

final totalCartPriceInt = instance.totalCartPriceInt;
copied to clipboard
itemCount
Returns the number of items currently in the cart.
final instance = ShoppingCart.getInstance<FoodModel>();

final cartLength = instance.itemCount;
copied to clipboard
This is same as instance.cartItems.length
cartItemsStream
A stream of cartItems that emits whenever the list of items in the cart changes.
class CartITemsStreamWidgetExample extends StatelessWidget {
const CartITemsStreamWidgetExample({super.key});

@override
Widget build(BuildContext context) {

// Get cart instance
final cartInstance = ShoppingCart.getInstance<FoodModel>();

// Stream will return List<YOUR ITEM MODEL>
return StreamBuilder<List<FoodModel>>(

// pass getter cartITemsStream
stream: cartInstance.cartItemsStream,

// Pass the cartItems as initialData
// to the stream builder, otherwise, the stream builder will
// initially return an empty list.
initialData: cartInstance.cartItems,
builder: (context, AsyncSnapshot<List<FoodModel>> snap) {

// retrive data from snaphot and use it
final List<FoodModel> items = snap.data!;

return; /// return any widget you need
},
);
}
}
copied to clipboard
Methods #
Get item from cart
Returns the item from cartItems that matches the given itemModel.
final instance = ShoppingCart.getInstance<FoodModel>();

final item = instance.getItemFromCart(yourItemModel);
copied to clipboard
This method is mainly used for all other methods, such as increasing the quantity of an item, decreasing it, deleting it, updating it. But in some cases, you may also need it.
Finding an item by ID
To find an item in the cart by ID, call the findItemById method on the Cart instance:
final instance = ShoppingCart.getInstance<FoodModel>();

final item = instance.findItemById(1);
copied to clipboard
Has item with id
Returns true if an item with the specified id is already in the cart. Returns false otherwise.
final instance = ShoppingCart.getInstance<FoodModel>();

// return true if item with the specified `id` is already in the cart
// return false if item with the specified `id is is not added to the cart
// Throw ArgumentError if id <= 0
final bool result = instance.hasItemWithId(1);
copied to clipboard
Contains cart item
This method checks if the item is already in the cart.
This is like method getItemFromCart, but this method will return a bool value
final instance = ShoppingCart.getInstance<FoodModel>();

// Returns true if the [itemModel] is already in the cart.
// Returns false if not
final bool result = instance.containsCartItem(yourItemModel);
copied to clipboard
Adding items to the cart
To add an item to the cart, simply call the addItemToCart method on the Cart instance:
final instance = ShoppingCart.getInstance<FoodModel>();

// create your item model
final item = FoodModel(
id: 1,
name: 'Cheeseburger',
price: 8.99,
urlPhoto: 'https://example.org/Cheeseburger',
);

// add item to the cart
instance.addItemToCart(item);
copied to clipboard
If the item already exists in the cart, its quantity will be increased by one.
Removing items from the cart
To remove an item from the cart, call the removeItemFromCart method on the Cart instance:
final instance = ShoppingCart.getInstance<FoodModel>();

// Pass your item model as argument
// This method will find the right model in cart items and it will remove it
instance.removeItemFromCart(item);
copied to clipboard
Increment item quantity
Increases the quantity of an item in the cart by one.
final instance = ShoppingCart.getInstance<FoodModel>();

// It will fint the right item in cartItem and it will
// increment quantity by 1.
instance.incrementItemQuantity(yourItem);
copied to clipboard
Decrement item quantity
Decrement the quantity of an item in the cart by one.
final instance = ShoppingCart.getInstance<FoodModel>();

// It will fint the right item in cartItem and it will
// decrement quantity by 1.
instance.decrementItemQuantity(yourItem);
copied to clipboard
if the quantity of item is equal to 1, it will remove your item from cart!
Calculate item total price by ID
Calculates the total price of an item with the specified id in the cart.
final instance = ShoppingCart.getInstance<FoodModel>();

// Returns the total price of the item,
// which is the product of the item's price and quantity.
/// Throws an [ArgumentError] if the [id] is not valid.
final double totalPrice = instance.calculateItemTotalPriceById(1);
copied to clipboard
But you can also use the getter calculateTotalItemPrice from ItemModel. It will do the same.
For example
final instance = ShoppingCart.getInstance<FoodModel>();

// get your item instance
final item = instance.findItemById(1);

/// The total price of the item calculated
/// by multiplying price with quantity.
final double totalItemPrice = item.calculateTotalItemPrice;
copied to clipboard
Update item
In some case you may need to update your item model values.
final instance = ShoppingCart.getInstance<FoodModel>();

instance.updateItemInCart(oldModel, updatedModel);
copied to clipboard
Throws a StateError if the old item is not found in the cart.
If the old and new items are the same and have the same quantity, no update is performed.
If the new item's quantity is 0, the old item will be removed from the cart.
The cartItems will be updated and refreshed after the item is updated or removed.
Parameters:

oldItem: The old item in the cart to be updated.
newItem: The new item to replace the old item in the cart.

The full example of using this method will be shown below.
Refresh cart
Use this method to update the UI after updating the values in your product model.
final instance = ShoppingCart.getInstance<FoodModel>();

instance.refreshCart();
copied to clipboard
But do not use this method with other methods of this package as they already use it by default.
Clear all items
To clear all items from the cart, call the clearCart method on the Cart instance:
final instance = ShoppingCart.getInstance<FoodModel>();

instance.clearCart();
copied to clipboard
Rebuild ui #
Most likely, you will want to update (redraw) the ui, for example, when a new item is added to the cart, or when the total cost of all items in the cart is updated.
As I mentioned before, cartItems is observable and uses Get for this purpose. Below, I will show two ways to rebuild the ui when performing any manipulations with cartItems.
And for this, you won't need to use StatefulWidgets and SetState!
Use Get
For example, let's say we need to display the total price of items in the cart on the screen, but we also need the widget with the total price to be redrawn every time the user, for example, removes an item from the cart or changes its quantity.
class TotalCartPriceWidget extends StatelessWidget {
const TotalCartPriceWidget({super.key});

@override
Widget build(BuildContext context) {

// get cart instance
final cartInstance = ShoppingCart.getInstance<FoodModel>();

// get cart total
final cartTotal = cartInstance.cartTotal;

// text widget with cart total
return Text('Cart total $cartTotal');
}
}
copied to clipboard
If you will try to use it, you will see, that when you try for example remove one item from cart, your ui will not rebuild.
For make it rebuild you need to wrap your Text widget with Obx widget witch come from Get package and it will work fine
class TotalCartPriceWidget extends StatelessWidget {
const TotalCartPriceWidget({super.key});

@override
Widget build(BuildContext context) {
final cartInstance = ShoppingCart.getInstance<FoodModel>();
final cartTotal = cartInstance.cartTotal;

return Obx(
() => Text('Cart total $cartTotal');
);
}
}
copied to clipboard
All you need to redraw your ui, is to wrap any getter of this package with the Obx widget, and then every time cartItems is updated, your UI will be redrawn! It's really easy!

Lets look for another example. For example we will display all items in cart in list and by long tap we will remove item from cart and it will rebuild ui automatically!
class ItemsListWidget extends StatelessWidget {
const ItemsListWidget({super.key});

@override
Widget build(BuildContext context) {

// get cart instance
final instance = ShoppingCart.getInstance<FoodModel>();

// Use Obx widget for make ui rebuild any time
// when cartItems is updated
return Obx(
() => ListView.builder(
itemBuilder: (context, int index) {

// get single item from cartItems by index
final item = instance.cartItems[index];

return ListTile(
title: Text(item.name),
leading: Image.network(item.urlPhoto),
trailing: Text('${item.calculateTotalItemPrice}'),

// remove item from cart onLongPressEvent
// it will rebuild your ui automatically
onLongPress: () => instance.removeItemFromCart(item),
);
},
// pass cart items length by using getter `itemCount`
itemCount: instance.itemCount,
),
);
}
}
copied to clipboard
About how Obx works, you can read on the Get package page.
You can check out a complete example of using this package by downloading the example project from Github repo and running it on your machine. Everything is already set up and working there. I tried to use all the features of this package in that project!

Use StreamBuilder
If for some reason you don't want to use Get, I have also created a stream that returns the cartItems.
Example of usage
class ItemsListStreamWidget extends StatelessWidget {
const ItemsListStreamWidget({super.key});

@override
Widget build(BuildContext context) {
// get cart instance
final instance = ShoppingCart.getInstance<FoodModel>();

return StreamBuilder(
// pass cartItemsStream
stream: instance.cartItemsStream,

// pass cartItems as initialData, it will return the current state of cartItems.
initialData: instance.cartItems,
// snapshot will return you a List<YOUR ITEM MODEL>, in my case FoodModel
builder: (context, AsyncSnapshot<List<FoodModel>> snap) {

// get data from snapshot
final List<FoodModel> data = snap.data!;

// Next return any widget you want and ui will rebuild automatically
//when cartITems was updated
return ListView.builder(
itemBuilder: (context, int index) {
// get single item from cartItems by index
final item = data[index];

return ListTile(
title: Text(item.name),
leading: Image.network(item.urlPhoto),
trailing: Text('${item.calculateTotalItemPrice}'),

// remove item from cart onLongPressEvent
// it will rebuild your ui automatically
onLongPress: () => instance.removeItemFromCart(item),
);
},
itemCount: instance.itemCount,
);
},
);
}
}
copied to clipboard
Conclusion #
Thank you for watching until the end! I hope I was able to explain how this package works. But if you still have any questions, you can write to me on Telegram or GitHub, and I will try to help as much as possible.
I created this package for myself, as I often develop applications with a shopping cart. This package speeds up my work, and I hope it will help you too.

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files:

Customer Reviews

There are no reviews.