Я очень рекомендую использовать средство форматирования кода в вашем коде, поскольку это значительно повышает вероятность того, что люди смогут обнаружить проблемы, подобные той, что у вас есть. Когда я переформатирую первый кодовый блок, которым вы поделились, он становится:
void submitOrder() async {
List<CartItem> products = [];
double total = 0;
CartItem temp = CartItem(
customerId: '', itemId: '', id: '', title: '', quantity: 0, price: 0);
DatabaseService().cartCollection.getDocuments().then(
(snapshot) => snapshot.documents.forEach((doc) {
temp = CartItem(
customerId: user.uid,
itemId: doc.data['itemId'].toString(),
id: doc.documentID.toString(),
title: doc.data['itemName'].toString(),
quantity: int.tryParse(doc.data['quantity'].toString()),
price: double.tryParse(doc.data['price'].toString()));
total += temp.quantity * temp.price;
print(total);
/// This print shows accurate total
products.add(temp);
}),
);
// Send data to setOrderData in db class to set new doc in order collection
DatabaseService().setOrderData(products, total, user.uid, branchId, 'open');
}
. В этом формате мне сразу становится ясно, что вы звоните setOrderData
до того, как произойдет любой из вызовов products.add(temp)
.
Это потому, что данные загружаются из Firestore асинхронно. Поскольку это может занять некоторое время, ваш основной код (включая return
) продолжается, поэтому пользовательский интерфейс не блокируется. Затем, когда данные доступны, вызывается ваш обратный вызов then
.
Это означает, что любой код, которому нужны данные из Firestore, должен находиться внутри обратного вызова then
. Таким образом, в вашем случае, решение может быть таким же простым, как перемещение вызова на setOrderData
внутрь then
:
void submitOrder() async {
List<CartItem> products = [];
double total = 0;
CartItem temp = CartItem(
customerId: '', itemId: '', id: '', title: '', quantity: 0, price: 0);
DatabaseService().cartCollection.getDocuments().then(
(snapshot) => snapshot.documents.forEach((doc) {
temp = CartItem(
customerId: user.uid,
itemId: doc.data['itemId'].toString(),
id: doc.documentID.toString(),
title: doc.data['itemName'].toString(),
quantity: int.tryParse(doc.data['quantity'].toString()),
price: double.tryParse(doc.data['price'].toString()));
total += temp.quantity * temp.price;
print(total);
/// This print shows accurate total
products.add(temp);
}),
// Send data to setOrderData in db class to set new doc in order collection
DatabaseService().setOrderData(products, total, user.uid, branchId, 'open');
);
}
Итак, что нужно от этого отнять:
- Всегда форматируйте свой код, так как вам и другим будет проще понять поток и найти проблемы.
- Данные загружаются из Firestore (и большинства облачных API) асинхронно, и вы можете использовать только данные внутри обратного вызова
then()
или с помощью await
.