Skip to content

Instantly share code, notes, and snippets.

@hectorAguero
Created June 13, 2025 13:25
Show Gist options
  • Save hectorAguero/fff608870f54f9d6aa4dc5803a3ef4f0 to your computer and use it in GitHub Desktop.
Save hectorAguero/fff608870f54f9d6aa4dc5803a3ef4f0 to your computer and use it in GitHub Desktop.
Bloc with ShoppingCart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Shopping Cart App',
theme: ThemeData(primarySwatch: Colors.blue),
home: const ShoppingCartPage(),
);
}
}
class ShoppingCartPage extends StatelessWidget {
const ShoppingCartPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Shopping Cart')),
body: BlocProvider(
create: (context) => ShoppingCartCubit(),
child: const ShoppingCartView(),
),
);
}
}
class ShoppingCartView extends StatelessWidget {
const ShoppingCartView({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<ShoppingCartCubit, ShoppingCartState>(
builder: (context, state) {
if (state is ShoppingCartInitial) {
return const Center(child: CircularProgressIndicator());
} else if (state is ShoppingCartLoaded) {
return ListView.builder(
itemCount: state.items.length,
itemBuilder: (context, index) {
final item = state.items[index];
return BlocProvider(
// Provide unique keys to BLoCs
//key: Key(item.id.toString()),
create: (context) => CartItemCubit(item),
child: CartItemWidget(item: item),
);
},
);
} else if (state is ShoppingCartError) {
return Center(child: Text('Error: ${state.message}'));
} else {
return const Center(child: Text('Unknown state'));
}
},
);
}
}
class CartItemWidget extends StatelessWidget {
const CartItemWidget({super.key, required this.item});
final CartItem item;
@override
Widget build(BuildContext context) {
return BlocBuilder<CartItemCubit, CartItemState>(
builder: (context, state) {
return Card(
margin: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(item.name),
Row(
children: [
IconButton(
icon: const Icon(Icons.remove),
onPressed: state.quantity > 0
? () => context.read<CartItemCubit>().decrement()
: null,
),
Text('${state.quantity}'),
IconButton(
icon: const Icon(Icons.add),
onPressed: () =>
context.read<CartItemCubit>().increment(),
),
],
),
],
),
),
);
},
);
}
}
// Data Model
class CartItem {
final int id;
final String name;
CartItem({required this.id, required this.name});
}
// Cart Item Cubit
sealed class CartItemState {
final int quantity;
CartItemState({required this.quantity});
}
class CartItemInitial extends CartItemState {
CartItemInitial({required super.quantity});
}
class CartItemUpdated extends CartItemState {
CartItemUpdated({required super.quantity});
}
class CartItemCubit extends Cubit<CartItemState> {
final CartItem item;
CartItemCubit(this.item) : super(CartItemInitial(quantity: 0));
void increment() {
emit(CartItemUpdated(quantity: state.quantity + 1));
}
void decrement() {
if (state.quantity > 0) {
emit(CartItemUpdated(quantity: state.quantity - 1));
}
}
}
// Shopping Cart Cubit
sealed class ShoppingCartState {}
class ShoppingCartInitial extends ShoppingCartState {}
class ShoppingCartLoaded extends ShoppingCartState {
final List<CartItem> items;
ShoppingCartLoaded({required this.items});
}
class ShoppingCartError extends ShoppingCartState {
final String message;
ShoppingCartError({required this.message});
}
class ShoppingCartCubit extends Cubit<ShoppingCartState> {
ShoppingCartCubit() : super(ShoppingCartInitial()) {
loadItems();
}
Future<void> loadItems() async {
try {
// Simulate loading items from a data source
await Future.delayed(const Duration(seconds: 1));
final items = [
CartItem(id: 1, name: 'Apple'),
CartItem(id: 2, name: 'Banana'),
CartItem(id: 3, name: 'Orange'),
];
emit(ShoppingCartLoaded(items: items));
} catch (e) {
emit(ShoppingCartError(message: 'Failed to load items'));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment