product bloc class
final ProductRepositoryImpl _productRepositoryImpl;
ProductBloc(this._productRepositoryImpl) : super(ProductInitializing()) {
on<AddToCart>((event, emit) => _addToCart(event, emit));
on<RemoveFromCart>((event, emit) => _removeFromCart(event, emit));
}
Future _removeFromCart(
RemoveFromCart event, Emitter<ProductState> emit) async {
try {
final state = this.state;
if (state is ProductLoaded) {
List<ProductModel> productList = state.products.map((pro) {
if (pro.prodId == event.productModel.prodId) {
if (pro.count > 0) {
pro.count--;
}
}
return pro;
}).toList();
emit(ProductLoaded(products: productList));
}
} catch (e) {
emit(ProductError(message: "Not added to the cart"));
}
}
Future _addToCart(AddToCart event, Emitter<ProductState> emit) async {
try {
final state = this.state;
if (state is ProductLoaded) {
List<ProductModel> products = state.products.map((pro) {
if (pro.prodId == event.productModel.prodId) {
++pro.count;
}
return pro;
}).toList();
emit(ProductLoaded(products: products));
}
} catch (e, stack) {
print("somethign wrong ${stack.toString()}");
emit(ProductError(message: "Not added to the cart"));
}
}
}
product event class
abstract class ProductEvent extends Equatable {
const ProductEvent();
}
class AddToCart extends ProductEvent {
final ProductModel productModel;
const AddToCart(this.productModel);
@override
List<Object> get props => [productModel];
}
class RemoveFromCart extends ProductEvent {
final ProductModel productModel;
const RemoveFromCart(this.productModel);
@override
List<Object> get props => [productModel];
}
product state class
abstract class ProductState extends Equatable {
const ProductState();
}
class ProductInitializing extends ProductState {
@override
List<Object> get props => [];
}
class ProductLoading extends ProductState {
@override
List<Object> get props => [];
}
class ProductError extends ProductState {
String message;
ProductError({required this.message});
@override
List<Object> get props => [message];
}
class ProductLoaded extends ProductState {
final List<ProductModel> products;
const ProductLoaded({
required this.products,
});
@override
List<Object> get props => [products];
}
product list screen where i display the products
builder: ((context, state) {
final state = context.read<ProductBloc>().state;
if (state is ProductLoaded) {
return SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
return StatefulBuilder(builder: (context, setState) {
return ProductItem(
productModel: state.products[index],
addToCart: (product) {
context
.read<ProductBloc>()
.add(AddToCart(product));
},
removeFromCart: (product) {
product.count > 0 ? product.count-- : 0;
context
.read<ProductBloc>()
.add(RemoveFromCart(product));
},
);
});
},
childCount: state.products.length,
),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 1,
crossAxisSpacing: 1,
childAspectRatio: .6,
),
);
}
return const SliverToBoxAdapter(child: SizedBox.shrink());
}),
),
product Item class that are used inside listview
class ProductItem extends StatelessWidget {
const ProductItem(
{Key? key,
required this.productModel,
required this.addToCart,
required this.removeFromCart})
: super(key: key);
final ProductModel productModel;
final Function(ProductModel product) addToCart;
final Function(ProductModel product) removeFromCart;
@override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.zero,
color: Colors.grey[50],
elevation: 1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * .26,
width: double.infinity,
child: Card(
elevation: 0,
margin: EdgeInsets.zero,
semanticContainer: true,
color: secondaryLight,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0.0),
),
child: CachedNetworkImage(
imageUrl: productModel.prodImage ??
' https://picsum.photos/250?image=9 ',
errorWidget: (context, url, error) =>
Image.asset('assets/images/logo.png'),
fit: BoxFit.cover,
),
),
),
const SizedBox(
height: 5,
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
productModel.prodName!,
style: kLabelStyleBold,
),
Text(productModel.prodCode!),
Text(productModel.prodMrp!),
],
),
)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: IconButton(
onPressed: () => removeFromCart(productModel),
icon: const Icon(Icons.remove_circle_outline),
),
),
Builder(builder: (context) {
context.watch<ProductBloc>().state;
return Flexible(
child: Text(
productModel.count.toString(),
style: kLabelStyleBold.copyWith(
fontSize: 22,
),
),
);
}),
Flexible(
child: IconButton(
onPressed: () => addToCart(productModel),
icon: const Icon(Icons.add_circle_outline),
),
),
],
),
],
),
);
}
}
in product item widget there are two buttons to manage the product counter but unfortunately i am not able to get the updated list using bloc. although i can see the log of bloc that event gets executed and values are updated but when emitting the updated list it doesn't reflect on the UI, any help would be appreciated
logs when the products load and counter button hit
I/flutter ( 1527): LoadPrdoucts()
I/flutter ( 1527): product from local db 5
I/flutter ( 1527): ProductBloc Transition { currentState: ProductInitializing(), event: LoadPrdoucts(), nextState: ProductLoaded([ProductModel(), ProductModel(), ProductModel(), ProductModel(), ProductModel()]) }
I/flutter ( 1527): ProductBloc Change { currentState: ProductInitializing(), nextState: ProductLoaded([ProductModel(), ProductModel(), ProductModel(), ProductModel(), ProductModel()]) }
E/FlutterJNI( 1527): Failed to decode image
E/FlutterJNI( 1527): android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.
E/FlutterJNI( 1527): at android.graphics.ImageDecoder.nCreate(Native Method)
E/FlutterJNI( 1527): at android.graphics.ImageDecoder.access$200(ImageDecoder.java:169)
E/FlutterJNI( 1527): at android.graphics.ImageDecoder$ByteBufferSource.createImageDecoder(ImageDecoder.java:246)
E/FlutterJNI( 1527): at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1754)
E/FlutterJNI( 1527): at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1747)
E/FlutterJNI( 1527): at io.flutter.embedding.engine.FlutterJNI.decodeImage(FlutterJNI.java:524)
I/flutter ( 1527): AddToCart(ProductModel())
I/flutter ( 1527): AddToCart(ProductModel())
I/flutter ( 1527): AddToCart(ProductModel())
I/flutter ( 1527): RemoveFromCart(ProductModel())
I/flutter ( 1527): RemoveFromCart(ProductModel())