I am trying to get the productID from the list of products in my cart bloc and then merge the list with the cart quantity so that the end result is this:
"aos": [
{
"product_id": 10,
"quantity": 1
},
{
"product_id": 11,
"quantity": 2
}
],
I have tried to encode the map as a json, but there is still no option for me to access the id of each product. Please can someone point me in the right direction? My Checkout Screen:
class CheckoutScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// final List<dynamic> aos;
return Scaffold(
appBar: AppBar(
backgroundColor: buttonBG,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShippingAddress(),
const SizedBox(height: 20),
BlocBuilder<CartBloc, CartState>(
builder: (context, state) {
if (state is CartLoaded) {
Map aos = state.cart.productQuantity(state.cart.products);
var pio = aos.keys.toList();
String productInstance = json.encode(pio);
debugPrint(productInstance);
return Expanded(
child: SizedBox(
height: 400,
child: ListView.builder(
itemCount: aos.keys.length,
itemBuilder: (BuildContext context, int index) {
final pIndex = aos.keys.elementAt(index);
final qIndex = aos.values.elementAt(index);
return ProductCard.summary(
product: pIndex,
quantity: qIndex,
);
},
),
),
);
}
return const Text('Something went wrong');
},
),
],
));
}
}
Is there a way to achieve that because i am using bloc? Below is my CartModel:
import 'package:afia4_shopping_app/logic/models/product_models.dart';
import 'package:equatable/equatable.dart';
class Cart extends Equatable {
final List<ProductModel> products;
const Cart({this.products = const <ProductModel>[]});
@override
List<Object?> get props => [products];
Map productQuantity(products) {
var quantity = {};
products.forEach((product) {
if (!quantity.containsKey(product)) {
quantity[product] = 1;
} else {
quantity[product] = 1;
}
});
return quantity;
}
}
For the cartBloc:
class CartBloc extends Bloc<CartEvent, CartState> {
CartBloc() : super(CartLoading()) {
on<LoadCart>(_onLoadCart);
on<AddProduct>(_onAddProduct);
on<RemoveProduct>(_onRemoveProduct);
}
void _onLoadCart(
LoadCart event,
Emitter<CartState> emit,
) async {
emit(CartLoading());
try {
await Future<void>.delayed(const Duration(seconds: 1));
emit(CartLoaded());
} catch (_) {
emit(CartError());
}
}
void _onAddProduct(
AddProduct event,
Emitter<CartState> emit,
) {
if (state is CartLoaded) {
try {
emit(
CartLoaded(
cart: Cart(
products: List.from((state as CartLoaded).cart.products)
..add(event.product),
),
),
);
} on Exception {
emit(CartError());
}
}
}
void _onRemoveProduct(
RemoveProduct event,
Emitter<CartState> emit,
) {
if (state is CartLoaded) {
try {
emit(
CartLoaded(
cart: Cart(
products: List.from((state as CartLoaded).cart.products)
..remove(event.product),
),
),
);
} on Exception {
emit(CartError());
}
}
}
}
For the productModel:
class ProductModel {
ProductModel(
{this.name,
this.id,
});
String? name;
int? id;
factory ProductModel.fromJson(Map<String, dynamic> json) => ProductModel(
name: json["name"],
id: json["id"],
Map<String, dynamic> toJson() => {
"name": name,
"id": id
};
List<ProductModel> productsFromJson(String str) => List<ProductModel>.from(
json.decode(str).map((x) => ProductModel.fromJson(x)));
String productsToJson(List<ProductModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
}
CodePudding user response:
If you add this dependency: collection: ^1.16.0
, and include that:
import "package:collection/collection.dart";
You can use the groupListsBy()
method and run:
var group = cart.products.groupListsBy((element) => element.id).map((key, value) => MapEntry(key, value.length));
Which will give you a Map<int?, int>
grouping product id to the quantity.
You can then present it as you wish in your UI.