Flutter:无法从 FutureBuilder 上的 Future 函数检索数据
Flutter: Cannot retrieve data from a Future function on FutureBuilder
我正在使用 Veryfi 提供的 Flutter OCR 插件构建收据扫描仪。
这是一个读取图像的 Stream 函数和 returns 一个包含必要值的动态数组。
请注意,VeryfiDart
中的凭据已删除。
showImage
变量是从相机捕获或从图片库中选择的图像文件。
class ReceiptProcessor {
Future<dynamic> processReceipt(File image) async {
List<List<Widget>> itemList = [];
Uint8List imageData = image.readAsBytesSync();
String fileData = base64Encode(imageData);
VeryfiDart client = VeryfiDart(
'ClientId',
'ClientSecret',
'Username',
'ApiKey',
);
await client.processDocument('receipt.jpg', fileData).then(
(response) {
String totalPayment = response['total'].toString();
String currencyCode = response['currency_code'];
String vendorName = response['vendor']['name'];
for (var item in response['line_items']) {
String description = item['description'];
String quantity = item['quantity'].toString();
String totalCost = item['total'].toString();
List<Widget> itemInfo = [
Text(description),
Text(quantity),
Text(totalCost)
];
itemList.add(itemInfo);
}
List<dynamic> processedDetails = [
Text(totalPayment),
Text(currencyCode),
Text(vendorName),
itemList
];
return processedDetails;
},
).catchError((error) {
return Text('Error');
});
}
}
显然数据已正确获取,但在尝试检索数据并显示时出现问题。
class ReceiptDetailsView extends StatefulWidget {
const ReceiptDetailsView({Key? key}) : super(key: key);
@override
State<ReceiptDetailsView> createState() => _ReceiptDetailsViewState();
}
class _ReceiptDetailsViewState extends State<ReceiptDetailsView> {
Future<dynamic> loadProcessedReceipt() async {
ReceiptProcessor rp = ReceiptProcessor();
return await rp.processReceipt(showImage!);
}
late Future<dynamic> processedReceipt;
@override
void initState() {
super.initState();
processedReceipt = loadProcessedReceipt();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10.0),
child: FutureBuilder<dynamic>(
future: processedReceipt,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return CircularProgressIndicator();
case ConnectionState.done:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else if (snapshot.data != null) {
return Text('Success');
}
}
return Text('Error');
},
),
);
}
}
我这里用了一个FutureBuilder
,但是连续返回一个包含空数据的空快照;因此,'Error'
显示在视图上。
如有任何建议,我们将不胜感激。正确检索快照数据时,应该会出现 'Success'
文本。
我认为你的函数确实 return 没有任何作用。主要是因为您使用了 then
函数。由于您 return 在 then
回调中,因此该值不是 return 全局编辑的,而是仅针对此函数。
有两个选项,您可以 return 您在 then
回调中解析的值,如下所示:
return await client.processDocument(..).then(...);
或者根本不使用 then
,而是继续依赖 await
:
Map<String, dynamic> response = await client.processDocument(...);
...
return processedDetails;
我推荐后一种情况,其中单个 return 只是来自函数本身的 return,并且您不在嵌套回调函数中包含一些代码。
我正在使用 Veryfi 提供的 Flutter OCR 插件构建收据扫描仪。
这是一个读取图像的 Stream 函数和 returns 一个包含必要值的动态数组。
请注意,VeryfiDart
中的凭据已删除。
showImage
变量是从相机捕获或从图片库中选择的图像文件。
class ReceiptProcessor {
Future<dynamic> processReceipt(File image) async {
List<List<Widget>> itemList = [];
Uint8List imageData = image.readAsBytesSync();
String fileData = base64Encode(imageData);
VeryfiDart client = VeryfiDart(
'ClientId',
'ClientSecret',
'Username',
'ApiKey',
);
await client.processDocument('receipt.jpg', fileData).then(
(response) {
String totalPayment = response['total'].toString();
String currencyCode = response['currency_code'];
String vendorName = response['vendor']['name'];
for (var item in response['line_items']) {
String description = item['description'];
String quantity = item['quantity'].toString();
String totalCost = item['total'].toString();
List<Widget> itemInfo = [
Text(description),
Text(quantity),
Text(totalCost)
];
itemList.add(itemInfo);
}
List<dynamic> processedDetails = [
Text(totalPayment),
Text(currencyCode),
Text(vendorName),
itemList
];
return processedDetails;
},
).catchError((error) {
return Text('Error');
});
}
}
显然数据已正确获取,但在尝试检索数据并显示时出现问题。
class ReceiptDetailsView extends StatefulWidget {
const ReceiptDetailsView({Key? key}) : super(key: key);
@override
State<ReceiptDetailsView> createState() => _ReceiptDetailsViewState();
}
class _ReceiptDetailsViewState extends State<ReceiptDetailsView> {
Future<dynamic> loadProcessedReceipt() async {
ReceiptProcessor rp = ReceiptProcessor();
return await rp.processReceipt(showImage!);
}
late Future<dynamic> processedReceipt;
@override
void initState() {
super.initState();
processedReceipt = loadProcessedReceipt();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10.0),
child: FutureBuilder<dynamic>(
future: processedReceipt,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return CircularProgressIndicator();
case ConnectionState.done:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else if (snapshot.data != null) {
return Text('Success');
}
}
return Text('Error');
},
),
);
}
}
我这里用了一个FutureBuilder
,但是连续返回一个包含空数据的空快照;因此,'Error'
显示在视图上。
如有任何建议,我们将不胜感激。正确检索快照数据时,应该会出现 'Success'
文本。
我认为你的函数确实 return 没有任何作用。主要是因为您使用了 then
函数。由于您 return 在 then
回调中,因此该值不是 return 全局编辑的,而是仅针对此函数。
有两个选项,您可以 return 您在 then
回调中解析的值,如下所示:
return await client.processDocument(..).then(...);
或者根本不使用 then
,而是继续依赖 await
:
Map<String, dynamic> response = await client.processDocument(...);
...
return processedDetails;
我推荐后一种情况,其中单个 return 只是来自函数本身的 return,并且您不在嵌套回调函数中包含一些代码。