[英]What is the proper way to fetch a Future variable within my flutter stateful widget
如何確保我的 batchNo 在我的 for 循環中的每次迭代中得到更新? 我對解決這個問題的“正確”方法感到困惑。 我猜我應該在本地初始化 batchNo 並將其更新為 go 而不是每次調用 loadAndUploadCsvData() 時都獲取它。 我嘗試在我的 initState() 中聲明一個本地 _batchNo 但我不確定如何訪問這個變量。 我嘗試在我的 _TestUploadState 中創建一個 localVariable,但我不確定如何在 Widget 構建中更新變量,因為它不是未來的構建。
發生了什么:batchNo 不會在 for 循環中的每次迭代中得到更新,因此數據全部存儲在一個文檔中。 batchNo 從 firebase 獲取(即 batchNo = 1),在循環的第二次迭代時 batchNo 保持 1 並且可能由於缺少 await 關鍵字而未更新。
預期:我希望在 for 循環中的每次迭代中更新 batchNo,因此每次迭代都會創建一個單獨的文檔。 batchNo 從 firebase 獲取(即 batchNo = 1),在循環的第二次迭代中 batchNo 得到更新並且 batchNo = 2。
class TestUpload extends StatefulWidget {
const TestUpload({super.key});
@override
_TestUploadState createState() => _TestUploadState();
}
class _TestUploadState extends State<TestUpload> {
Widget build(BuildContext context) {
// batchNo not updating within for loop
for (BatchData batchData in _batchDataList) {
loadAndUploadCsvData(batchData.name, batchData.bytes);
}
}
void loadAndUploadCsvData(String name, Uint8List? bytes) async {
// First batchNo call is not updated on subsequent batchNo
int batchNo = await getNextBatchNo();
// Send current batch to firebase
FirebaseFirestore.instance
.collection('availableBatches')
.doc("batch" "$batchNo")
.set({"batchNo": batchNo});
}
// Gets next batch no from firebase from document names
Future<int> getNextBatchNo() async {
QuerySnapshot batchCollection = await FirebaseFirestore.instance
.collection('availableBatches')
.orderBy('batchNo', descending: true)
.get();
// If collection doesn't exist
if (batchCollection.docs.isEmpty) {
return 1;
}
int batchNo = batchCollection.docs[0].get('batchNo');
return batchNo + 1;
}
}
我試過這樣做
class TestUpload extends StatefulWidget {
const TestUpload({super.key});
@override
_TestUploadState createState() => _TestUploadState();
}
class _TestUploadState extends State<TestUpload> {
int _batchNo = 1;
int iteration = 0;
final List<BatchData> _batchDataList = [];
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.all(8),
child: Column(
children: [
const SizedBox(
height: 12,
),
ElevatedButton(
onPressed: () {
for (BatchData batchData in _batchDataList) {
loadAndUploadCsvData(batchData.name, batchData.bytes);
log("iteration: $iteration");
iteration++;
log("_batchNo: $_batchNo");
updateBatchNo();
}
},
child: Text("TESTING")),
],
)),
);
}
void loadAndUploadCsvData(String name, Uint8List? bytes) async {
String extension = name.split('.').last;
int batchNo = await getNextBatchNo();
if (extension == 'xls' || extension == "xlsx") {
// Do some xls xlsx manipulation
var excel = Excel.decodeBytes(bytes!);
for (var table in excel.tables.keys) {
for (var row in excel.tables[table]!.rows) {
ContactModel currentContact;
// Skip first (header) row
if (row[0]!.colIndex == 0 && row[0]!.rowIndex == 0) {
continue;
}
// Create currentContact Model
currentContact = ContactModel(
name: row[0]!.value,
number: row[1]!.value,
type: row[2]!.value,
isCalled: false);
// Send current batch to firebase
_firestore
.collection('availableBatches')
.doc("batch" "$batchNo")
.set({"batchNo": batchNo});
// Send current contact to firebase
_firestore
.collection('availableBatches')
.doc("batch" "$batchNo")
.collection("batchCollection")
.add(currentContact.toMap());
}
}
}
}
Future<int> getNextBatchNo() async {
QuerySnapshot batchCollection = await FirebaseFirestore.instance
.collection('availableBatches')
.orderBy('batchNo', descending: true)
.get();
// If collection doesn't exist
if (batchCollection.docs.isEmpty) {
setState(() {
_batchNo = 1;
});
return 1;
}
int batchNo = batchCollection.docs[0].get('batchNo');
setState(() {
_batchNo = batchNo + 1;
});
return batchNo + 1;
}
void updateBatchNo() async {
int batchNo = await getNextBatchNo();
setState(() {
_batchNo = batchNo;
});
}
}
但是仍然在嘗試通過我的循環將我的詳細信息發送到 firestore 時
[log] iteration: 0
[log] _batchNo: 1
[log] iteration: 1
[log] _batchNo: 1
通過將我的void loadAndUploadCsvData(String name, Uint8List? bytes)
返回類型更改為Future<void> loadAndUploadCsvData(String name, Uint8List? bytes)
並在每次迭代前調用await
解決了這個問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.