我正在使用getx学习一个购物车教程,我遇到了一个问题,当购物车是空的时候,我收到“bad state no element”错误。我知道这是因为.reduce方法在列表为空时会产生这样的错误,但当我尝试使用.fold时,我会得到这样的错误:返回类型'num'不是'int',这是闭包上下文所要求的。
只有一个问题,我发现和我的问题是相同的,但我不明白选择的答案。我一直在寻找答案,但到目前为止,没有一个答案对我有用。
这里是问题的链接:How to identify the List is empty, to avoid the Bad state: No element for ListMixin.reduce
这是我的控制器:
import 'package:get/get.dart';
import 'package:plantel/screens/widgets/product_model.dart';
class CartController extends GetxController {
final _products = {}.obs;
void addProduct(Product product) {
if (_products.containsKey(product)) {
_products[product] += 1;
} else {
_products[product] = 1;
}
}
void removeProduct(Product product) {
if (_products.containsKey(product) && _products[product] == 1) {
_products.removeWhere((key, value) => key == product);
} else {
_products[product] -= 1;
}
}
get productSubtotal => _products.entries
.map((product) => product.key.price * product.value)
.toList();
get total => _products.entries
.map((product) => product.key.price * product.value)
.toList()
.reduce((value, element) => value + element)
.toStringAsFixed(2);
get products => _products;
}
这里是产品控制器,我使用Cloud Firestore数据库来获取列表。
import 'package:get/get.dart';
import 'package:plantel/screens/widgets/firestore_db.dart';
import 'package:plantel/screens/widgets/product_model.dart';
class InDoorProductController extends GetxController {
final products = <Product>[].obs;
@override
void onInit() {
products.bindStream(FirestoreDB().getInDoorProducts());
super.onInit();
}
}
class OutDoorProductController extends GetxController {
final products = <Product>[].obs;
@override
void onInit() {
products.bindStream(FirestoreDB().getOutdoorProducts());
super.onInit();
}
}
class PotsAndVasesProductController extends GetxController {
final products = <Product>[].obs;
@override
void onInit() {
products.bindStream(FirestoreDB().getpotsandvasesProducts());
super.onInit();
}
}
class SoilsProductController extends GetxController {
final products = <Product>[].obs;
@override
void onInit() {
products.bindStream(FirestoreDB().getsoilsProducts());
super.onInit();
}
}
class PesticidesProductController extends GetxController {
final products = <Product>[].obs;
@override
void onInit() {
products.bindStream(FirestoreDB().getpesticidesProducts());
super.onInit();
}
}
下面是用于获取集合的FirestoreDB类。
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:plantel/screens/widgets/product_model.dart';
class FirestoreDB {
final FirebaseFirestore _firebaseFirestoreindoor = FirebaseFirestore.instance;
Stream<List<Product>> getInDoorProducts() {
return _firebaseFirestoreindoor
.collection('indoorplants')
.snapshots()
.map((snapshot) {
return snapshot.docs.map((doc) => Product.fromSnapshot(doc)).toList();
});
}
final FirebaseFirestore _firebaseFirestoreoutdoor =
FirebaseFirestore.instance;
Stream<List<Product>> getOutdoorProducts() {
return _firebaseFirestoreoutdoor
.collection('outdoorplants')
.snapshots()
.map((snapshot) {
return snapshot.docs.map((doc) => Product.fromSnapshot(doc)).toList();
});
}
final FirebaseFirestore _firebaseFirestorepotsandvases =
FirebaseFirestore.instance;
Stream<List<Product>> getpotsandvasesProducts() {
return _firebaseFirestorepotsandvases
.collection('potsandvases')
.snapshots()
.map((snapshot) {
return snapshot.docs.map((doc) => Product.fromSnapshot(doc)).toList();
});
}
final FirebaseFirestore _firebaseFirestoresoils = FirebaseFirestore.instance;
Stream<List<Product>> getsoilsProducts() {
return _firebaseFirestorepotsandvases
.collection('soils')
.snapshots()
.map((snapshot) {
return snapshot.docs.map((doc) => Product.fromSnapshot(doc)).toList();
});
}
final FirebaseFirestore _firebaseFirestorepesticides =
FirebaseFirestore.instance;
Stream<List<Product>> getpesticidesProducts() {
return _firebaseFirestorepotsandvases
.collection('pesticides')
.snapshots()
.map((snapshot) {
return snapshot.docs.map((doc) => Product.fromSnapshot(doc)).toList();
});
}
}
这是产品型号
import 'package:cloud_firestore/cloud_firestore.dart';
class Product {
final String title;
final int price;
final String subtitle;
final String image;
const Product(
{required this.title,
required this.price,
required this.subtitle,
required this.image});
static Product fromSnapshot(DocumentSnapshot snap) {
Product product = Product(
title: snap['title'],
price: snap['price'],
subtitle: snap['subtitle'],
image: snap['image']);
return product;
}
}
如果我添加了不必要的代码块,我很抱歉,但我添加它们是为了防止有人想了解我是如何获得列表的全貌。
1条答案
按热度按时间0x6upsns1#
Fold需要一个初始元素(通常称为累加器),如果列表为空,它也将是“默认”返回值。因此,要将此reduce:
我们只需要提供一个初始值:
如果someList为空,则返回0。
只要知道默认值,你总是可以将reduce重写为fold。你也可以反过来使用,将折叠重写为reduce:
所以这是另一种写法。:)
(Note但是,这需要初始值与其他元素的类型相同…当累加器是一个完全不同的类型时,fold也可以处理,这使得了解它非常有用。)